Winfx June CTP: What happened to InstanceContextMode.Shareable

The June CTP of WinFx introduces some breaking changes and the detailed API changes can be downloaded from here. One of the changes we made is to the InstanceContextMode enum. This enum denotes how WCF manages the InstanceContext lifetime. InstanceContext is the wrapper that the runtime creates for the service instance and this can be used to manage the lifetime of the service instance.  In its latest form, WCF supports only 3 modes Single, PerSession and PerCall. We removed the Shareable enum as we removed the inbuilt feature from the product. What I mean by inbuilt is that previously if you decorated your serivce to be Shareable, then clients could do,

IDummyService proxy;

EndpointAddress shareableAddress = ((IClientChannel)proxy).ResolveInstance();

The EndpointAddress returned from the service, points to an InstanceContext that is shareable. So if you use a ChannelFactory to connect to this EndpointAddress then two clients will be sharing one InstanceContext on the server.

So now with cutting Shareable, we removed ResolveInstance, Begin/EndResolveInstance from IClientChannel. No need to panic, as WCF still supports instance sharing via a newly added extensibility point. To implement sharing, users now need to use the System.ServiceModel.Dispatcher.IInstanceContextProvider extensibility point. Now to implement sharing users need to plug in their own implementation of IInstanceContextProvider and thereby decide which Session/Call from a client gets which InstanceContext. I wont go in detail on how to achieve this as we shipped a detailed sample in the SDK and it can be found under samples\TechnologySample\Extensibility\Instancing\Sharing. Do post back if you have any specific quesiton on the sample. What I want to do is explain very briefly how to look the individual methods in the new interface.

InstanceContext GetExistingInstanceContext (Message message, IContextChannel channel)

The runtime will call this method whenever a new Message is received on a channel (Gets called for every message on the channel). WCF will use the InstanceContext returned from this message to process the message. If null is returned then the system will always create a brand new InstanceContext to service this message. (The new InstanceContext created will have to go through the InstanceContext throttle acquiring process).

void InitializeInstanceContext (InstanceContext instanceContext, Message message, IContextChannel channel)

This method is called whenever the user returned null from the GetExistingInstanceContext method and the system decided to create a new InstanceContext. This way we notify the user that a new InstanceContext is created and they can add this to their InstanceContext cache.

bool IsIdle (InstanceContext instanceContext)

This method is called whenever WCF decides that all activites related to an InstanceContext is completed and checks with the user if it is idle. If the user returns true then the system will close the InstanceContext (and thereby releasing the InstanceContext throttle if it had acquired one).

void NotifyIdle (InstanceContextIdleCallback callback, InstanceContext instanceContext)

If the user returned false from the IsIdle call, then the system will not close the InstanceContext but call this method and pass a callback that the user need to call whenever they are done with the InstanceContext and they want it to be closed. Once the user calls the Callback, the system will once again call IsIdle and at that point if it returns true will then close the InstanceContext.

So if an IInstanceContextProvider is plugged in, then the InstanceContextMode flag set in ServiceBehavior attribute is no longer considered. Think of this as bypassing the WCF runtime's InstanceContext creation/management logic. The SDK sample denotes how to achieve sharing and also how to simulate PerCall, PerSession and Single behaviors just as an exercise.

Maheshwar Jayaraman [WCF]