If you want your resolved instances bound to the life time of a WCF operation then you can use the PerWebRequest lifestyle that comes with Windsor. However, this means making your services run in ASP.Net compatibility mode. This might not be ideal for your set of circumstances (as it wasn’t for mine). I did a great deal of googling around this subject and I couldn’t find anything someone had already done, so I thought I’d share this solution. Be great to get some feedback…
The solution works by plugging into to some of the extension points within WCF. I created a service behaviour (IServiceBehavior) which applies a Message Inspector to all operations (IDispatchMessageInspector). That message inspector does two things. For each new call it adds in a extension (IExtension<OperationContext>) to the operation context. This extension is where I’m going to stick all the instances which are bound to the operation. The second is to evict all instances from the container once the operation has completed.
All the lifestyle manager has to do is to check if there’s already an instance registered with the operation context (by looking in our custom extension). If it finds one, then it is returned, if not it will Resolve a new instance. This should give the same result as using PerWebRequest + ASP.Net compatibility mode…
Here’s all the code. Hope it helps!
Code for plugging into WCF:
You’ll need this bit of XML config. I will at some point change my stuff to use the WCF Facility in Castle, once I’ve done that I can add the behaviour programmatically…
And plugging into castle:
When you register the lifestyle with the container be sure to add it so it has a transient lifestyle itself (this means that there will be one WCF lifestyle manager per service type):
container.AddComponentLifeStyle("PerWcfMessage",typeof (PerWcfMessageLifestyleManager), LifestyleType.Transient)
Finally, just for a bit of context, the main thing which uses this lifestyle is my entity framework session… The lifestyle manager is a big win for me because it not only ensures there is only one session per service call, but that it is actually disposed (therefore, I don’t leak memory or connections to the DB).