Custom Integrations with Xamarin Workbooks
This document describes the integration SDK for Xamarin Workbooks. While integrations are most relevant to Xamarin Workbooks, it is important to note that they can also work with Xamarin Inspector.
Architecture Overview
Xamarin Workbooks features two main components which must work in conjunction with each other: Agent and Client.
Interactive Agent
The Agent component is a small platform-specific assembly which runs in the context of a .NET application.
Xamarin Workbooks provides pre-built "empty" applications for a number of platforms, such as iOS, Android, Mac and WPF. These applications explicitly host the agent.
During live inspection (Xamarin Inspector), the agent is injected via the IDE debugger into an existing application as part of the regular development & debugging workflow.
Interactive Client
The client is a native shell (Cocoa on Mac, WPF on Windows) that hosts a web browser surface for presenting the workbook/REPL interface. From an SDK perspective, all client integrations are implemented in JavaScript and CSS.
The client is responsible (via Roslyn) for compiling source code iinto small assemblies and sending them over to the connected agent for execution. Results of execution are sent back to the client for rendering. Each cell in a workbook yields one assembly which references the assembly of the previous cell.
Because an agent can be running on any type of .NET platform and has access to anything in the running application, care must be taken to serialize results in a platform-agnostic manner.
Representations
Within a workbook or inspector session, code that is executed and yields a result (e.g. a method returning a value or the result of an expression) is processed through the representation pipeline in the agent. All objects, with the exception of primitives such as integers, will be reflected to produce interactive member graphs and will go through a process to provide alternate representations that the client can render more richly. Objects of any size and depth are safely supported (including cycles and infinite enumerables) due to lazy and interactive reflection and remoting.
Xamarin Workbooks provides a few types common to all agents and clients that
allow for rich rendering of results. Color is one example of such a type,
where for example on iOS, the agent is responsible for converting CGColor or
UIColor objects into a Xamarin.Interactive.Representations.Color object.
In addition to common representations, the integration SDK provides APIs for serializing custom representations in the agent and rendering representations in the client.
External Integrations
Integration assemblies should reference the Xamarin.Interactive PCL.
Eventually the SDK will be released directly as a NuGet package, but for now any integrations should copy the SDK dependencies into their projects explicitly.
| Mac | /Library/Frameworks/Xamarin.Interactive.framework/Versions/Current/SDK |
|---|---|
| Windows | C:\Program Files (x86)\Xamarin\Workbooks\SDK |
Client integrations are initiated by placing JavaScript or CSS files with the
same name as the agent integration assembly in the same directory. For example,
if the agent integration assembly (which references the Xamarin.Interactive
PCL) is named SampleExternalIntegration.dll, then
SampleExternalIntegration.js and SampleExternalIntegration.css will be
integrated into the client as well if they exist. Client integrations are
optional.
The external integration itself can be packaged as a NuGet, provided and
referenced directly inside the application that is hosting the agent, or simply
placed alongside a .workbook file that wishes to consume it.
A workbook or live inspect session will load the integration by referencing the integration assembly.
#r "SampleExternalIntegration.dll"
The Xamarin.Interactive PCL provides a few important integration APIs. Every
integration must at least provide an integration entry point:
using Xamarin.Interactive;
[assembly: AgentIntegration (typeof (AgentIntegration))]
class AgentIntegration : IAgentIntegration
{
const string TAG = nameof (AgentIntegration);
public void IntegrateWith (IAgent agent)
{
// hook into IAgent APIs
}
}
At this point, once the integration assembly is referenced, the client will implicitly load JavaScript and CSS integration files.
APIs
As with any assembly that is referenced by a workbook or live inspect session, any of its public APIs are accessible to the session. Therefore it is important to have a safe and sensible API surface for users to explore.
The integration assembly is effectively a bridge between an application or SDK of interest and the session. It can provide new APIs that make sense specifically in the context of a workbook or live inspect session, or provide no public APIs and simply perform "behind the scenes" tasks like yielding object representations.
Note: APIs which must be public but should not be surfaced via IntelliSense
can be marked with the usual [EditorBrowsable (EditorBrowsableState.Never)]
attribute.
External Representations
Xamarin.Interactive.IAgent.RepresentationManager provides the ability to
register a RepresentationProvider, which an integration must implement to
convert from an arbitrary object to an agnostic form to render. These agnostic
forms must implement the ISerializableObject interface.
Note: APIs that produce ISerializableObject objects directly do not need
to be handled by a RepresentationProvider.
Rendering a Representation
Renderers are implemented in JavaScript and will have access to a JavaScript
version of the object represented via ISerializableObject. The JavaScript
copy will also have a $type string property that indicates the .NET type
name.
We recommend using TypeScript for client integration code, which of course compiles to vanilla JavaScript. Either way, the SDK provides typings which can be referenced directly by TypeScript or simply referred to manually if writing vanilla JavaScript is preferred.
The main integration point for rendering is
xamarin.interactive.RendererRegistry:
xamarin.interactive.RendererRegistry.registerRenderer(
function (source) {
if (source.$type === "SampleExternalIntegration.Person")
return new PersonRenderer;
return undefined;
}
);
Here, PersonRenderer implements the Renderer interface. See the
typings for more details.
Sample Integrations
See the Kitchen Sink sample for a working example of an
integration. Simply build KitchenSink.sln in Xamarin Studio or
Visual Studio and then open KitchenSink.workbook.

Let us know how you feel about this.
0/250
Xamarin Workbook
If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.