By default, when you install Indigo on a box, existing .NET Remoting / Enterprise Services / ASMX code runs unchanged. Depending on which technology, there is a small to medium quantity of work necessary to get this to use the Indigo stack.

The Indigo Connector is basically how we get a SOAP "dial tone" in an application. It's based on four simple concepts: 

  • A message is an in-memory SOAP envelope which enables you to code against SOAP.
  • A service is a piece of dev code that enables messages to be dispatched - a target for message delivery. 
  • Ports are a named location in the network space. 
  • Channels allow message I/O through a port.

Messages and services are visible to the outside world; conversely ports and channels are opaque to the outside world.

SOAP gives you a mechanism to communicate to the outside world. A SOAP message has a body which is largely intended to be opaque apart from to the sender and receiver. On the other hand, headers are the extensibility point in SOAP and are intended for everyone along the message path, including intermediary nodes. The same principles apply in Indigo. Indigo is fairly laissez-faire about the representation of the message: the wire format is an extensibility point that could be replaced. For example, if Indigo is used within an appdomain, it doesn't make sense to use an XML format.

An Indigo Message object therefore includes a Body (XmlReader type) and a Headers property (MessageHeader). A WriteXml method enables you to fill the body. In Beta 1 there will be a property bag on the Message too. You program it as if it is a SOAP 1.2 message.

Ports are locations in network space. A port resides in a single appdomain, and provides a base URI for all services that are sitting on the code side of the port. Ports act as factories for channels. A port has very few methods - initialisation methods, and the ability to create new channels; you create a channel by telling the port what you expect it to be doing. A channel is the object you perform message I/O on. The transport channel does the physical munging into the relevant format (HTTP, IPC or whatever).

A Port object includes CreateChannel() and a CreateListenerChannel() methods. Channels implement a base interface called IChannel, which implements the basic Open() and Close() methods. IInputChannel and IOutputChannel model a stream of messages, either from the push or the pull side. ServiceReferences are used to identify message recipients. They contain the absolute URI of a service plus some fixed headers.