Sunday, June 05, 2011

WCF Extensibility – IInstanceProvider

Moving down to the list of the extensibility points, the IInstanceProvider is actually quite useful when you have a service class which needs some initialization data. In most of the WCF service examples I’ve seen in the web, they’re simple classes, almost self-contained, which didn’t have any external dependencies. The default instancing behavior for WCF (simply call the parameter-less constructor for the service class) works perfectly in those cases. However, there are quite a few scenarios where this is not the case – the service depends on some database, the service class needs to listen to some external events, or we want to initialize the service class with a different parameter depending on the situation where it’s being used (or even on the incoming message which is being sent to it) – and the instance provider interface is the hook that the WCF extensibility provides to allow us total control over the instantiation of the service class. Another scenario where this may be useful is that if the service class only has a default constructor, but it does some heavy initialization, so you may want to create a pool of service instances – the instance provider can help in this case as well.


Public implementations in WCF

None. As with most runtime extensibility points, there are no public implementations in WCF. There are many internal implementations, such as the default System.ServiceModel.Dispatcher.InstanceProvider, which uses the default constructor for the service type to create the instances.
Interface declaration

public interface IInstanceProvider
{
    object GetInstance(InstanceContext instanceContext);
    object GetInstance(InstanceContext instanceContext, Message message);
    void ReleaseInstance(InstanceContext instanceContext, object instance);
}

The IInstanceProvider has two overloads of the GetInstance method used to create a new instance of the service class. The first one receives only an InstanceContext object, while the second one also receives an instance of the Message object which represents the request which is going to be sent to the service. In practice, the first one is seldom invoked – I could find in Reflector some code paths which called that one, but I couldn’t actually make a service in which that method was invoked after trying for about 30 minutes. It’s possible that it is invoked by some obscure code path, so if you’re implementing a custom one, and on the GetInstance(InstanceContext) you simply delegate the call to the other overload passing a null message, it’s nice to have the code consider that the message may in fact be null.

Read more: Carlos' blog