Indigo is constructed with layering as a central design principle. This means that in essence Indigo is actually a collection of sub-frameworks, each of which can be supplemented by ISV code (or replaced completely for that matter). Each framework is defined by two things:
- Fundamental unit(s) of data
- Transformations that can be applied to said data
Which (as you might be thinking) is another way of saying an object is defined by its members and its methods. This is true, but it’s more difficult (but very important) to stay focused on consistent pivots when constructing clean frameworks.
Indigo is built around the concept of a Message object. The structure of a Message object loosely represents a SOAP envelope, and consists of two distinct parts: the message’s body and an extensible collection of headers. The body is application-defined data, and headers are added/processed by infrastructure (and can also be used by the application). Access to a header or the body is achieved through XmlReader, as it contains structured data. It is this structured primitive which is the core of Indigo’s power (and which departs from the classic networking primitive of a byte array). It allows for extensible, interoperable protocols to be built, and for data contracts to be established.
At a high level, Indigo consists of two larger frameworks: the Typed Layer, and the Channel Layer.
The fundamental unit of data for the Channel Layer is Message. Channels are used to Send and Receive Messages. Channels come in two forms: Transport Channels and Layered Channels.
Transport Channels perform the actual send/receive of the Message to a network resource, including any necessary serialization.
Layered Channels perform a function based on the Message passed in, and then delegate further modification and transmission to their Inner Channel. So as you can see, even within a layer we have layers 🙂 Some examples of Layered Channels include Protocol Channels that use Message headers and infrastructure Messages to establish a higher-level protocol (such as WS-ReliableMessaging), and Reshaping Channels for changing the Message Exchange Pattern (such as converting an underlying [Send Channel, Receive Channel] pair into a Duplex Channel).
Message is a very flexible object, but to fully utilize it requires knowledge of Infosets and XML. What most developers instead will likely interface with is the Typed Layer. The fundamental unit of data for the Typed Layer is a CLR class. In the Typed Layer you create CLR objects that implement Services and Typed Proxies. The Typed Layer converts parameters and return values into Message objects and method calls into Channel calls. In this way, the Typed Layer builds on the functionality of the Channel Layer, and can transparently leverage any changes/improvements made to Channels.
Next I’ll provide an example to give you a flavor of this layering in action, stay tuned!