hoetz
hoetz

Reputation: 2388

WCF, Unity: Teardown disposable instances

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

Answers (2)

Andrew Savinykh
Andrew Savinykh

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

Ladislav Mrnka
Ladislav Mrnka

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

Related Questions