This is a rehash/update of a post I had made on my personal blog. I have made a couple of important updates to the code to fix the incorrect handling of Dispose() for a couple of the extensions. I have also updated the project to VS2010 and Unity 2.0.
While the original post referenced a non-Microsoft ORM I used in a previous company, the concept/problem still applies to many problems, including the Entity Framework and it’s associated ObjectContext.
In a nutshell, the problem with the application surfaced because I was naively using the the per-thread lifetime manager included with Unity within my WCF service. In the course of testing, I found that the objects using this lifetime manager seemed to occasionally persist across service calls. After spending a couple of minutes looking at stack traces and general debugging, it finally dawned on me what was happening. WCF's threading model, which was designed to make my services speedy, was actually causing the problem.
What was happening was that the same thread that was obtained in my first service call was being used to service my second service call. Because I was using the per-thread lifetime manager in Unity, the object was not going to be removed from the container until the associated thread went away. Well, in WCF, the threads don't ever really go away. Uh oh!
After talking with Scott (who luckily used to work on Unity), we came up with the idea to build a Unity lifetime manager tied to WCF's OperationContext. That way, our container objects would live only for the lifetime of the request, rather than the actual thread.
Starting with IExtension<OperationContext> and an implementation of IDispatchMessageInspector, I soon had an implementation of a UnityOperationContextLifetimeManager. Once we used this lifetime manager instead of the per-thread lifetime manager, the problem disappeared.
Once that was done, I figured that since I did one of the extensible objects in WCF, I might as well do the rest. The attached zip has lifetime managers to support all of the IExtensibleObject<T> implementations within WCF.
All of the lifetime managers are fairly straightforward, except for the UnityInstanceContextLifetimeManager. This depends on the InstanceContext of a given service on which it is enabled. PerSession is the default instancing mode for InstanceContext, but only when the transport supports sessions. If the transport does not support sessions, the instancing mode is essentially PerCall.
I have included the Unity assemblies in the zip file for ease of compilation, but if you plan on using any of this code, I would point the references to wherever you have your Unity assemblies.
I’m working on getting these added to Unity Contrib, but for now, just download the code..
Please note that the testing application is not necessarily a best practice for self-hosting a service, but I wanted you to see how to use the lifetime managers without having to worry about IIS (since IIS 6 doesn't have WAS and doesn't support the net.tcp binding). Make sure if you are on Windows 7/Vista, you run this sample application as admin.