Reputation: 2388
we've set up a WCF service which uses a Unity Container to resolve instances for managing Exchange 2010 Powershell commands. We defined an IExchangePowershell interface which has a concrete implementation that implements IDisposable. After some time we encountered the problem that we couldnt execute powershell commands anymore since the server said there are already too many powershell sessions open. It seems that we never really disposed of our powershell instances. The Dispose() method of the concrete Powershell would take care of closing the runspace and the session. Once I call this in the repository methods, we don't get the errors anymore.
((IDisposable)this.powershell).Dispose();
Now of course I dont want to explicitly call dispose in every repository method. I thought unity could take care of this. Our WCF Instance Provider does this:
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
container.Teardown(instance);
}
But that doesnt really dispose of the IExchangePowershell instances. Do you have any idea how I could automatically dispose of those instances?
Upvotes: 6
Views: 5512
Reputation: 26290
The answer depends on how you register your type / instance with unity. Standard implementation of Teardown does nothing at all.
If you register type then Unity does not store reference to instance it creates - it's up to you to manage it's lifetime and dispose it. If you register instance, then the instance lifetime is managed by unity and is kept until you dispose of the container.
The link below helps to understand a bit better about lifetime management: http://msdn.microsoft.com/en-us/library/ff648098.aspx
You need to ask yourself when you would like your objects to be disposed. If you know when to call ReleaseInstance, you might as well call IDispose instead of it.
(I'm sorry, I'm not familiar with WCF, so I'm not sure what instance provide is in this context)
Upvotes: 0
Reputation: 364329
That is actually well known problem in Unity. TearDown
method does nothing. If you want to use TearDown
you must create custom container extension.
I wrote an article about using object lifetimes managers in Unity and their impact on disposing. If you use default TransientLifetimeManager
or PerResolveLifetimeManager
the Unity will even don't track existence of your objects so it can't call Dispose
. The only lifetime managers which calls Dispose
on resolved instances are ContainerControlledLifetimeManager
(aka singleton) and HierarchicalLifetimeManager
. The Dispose
is called when the lifetime manager is disposed.
The solution for you is either use casting and handle Dispose
manually as you already did or switch to HiearchicalLifetimeManager
and create new subcontainer for each incoming WCF request. Each subcontainer will only handle single request and it will dispose resolved entities with hiearchical lifetime.
There are other ways, for example this article builds a very complex code around Unity to support disposing and TearDown
for all resolved objects.
Upvotes: 10