Extending Unity Container for IDisposable Instances (1st approach)

A few weeks ago, in my blog post ‘Who Disposes Your Repository’ I wrote about the challenges of implementing an IDisposable repository, which takes full advantage of the deferred execution of the IQueryable and, which is being injected through Dependency Injection (DI) into the classes that need to read or store data. I have focused the discussion on the case when the repository is abstracted by an interface, and its implementation is injected through DI. I have detailed more alternatives on how it could be disposed and the challenges that arise from the stateful nature of a repository, the deferred execution of the IQueryable and the DI.

In the end I have argued that especially for large applications, I would prefer that the Dependency Injection Container (DIC) disposes all the IDisposableinstances it created and it injected, including the repository. In short, the code that creates an IDisposable instance should also be responsible to call Dispose() on it.

In this post I will discuss some of the challenges of achieving this with Unity Container. By working to extend Unity with this functionality I have ended up implementing two approaches. In this post I will detail the first implementation I did, and in a next post I’ll explain the other.

There are many other writings on this. For example I have found useful the posts of Rory Primrose and of Marcel Veldhuizen who describe different approaches for disposing instances created by Unity. They both describe very well how Unity works and how it can be extended for this purpose. However, I was looking for an approach in which Unity remains unknown to the client code. I didn’t want the client code to call Teardown() or other Unity specific methods.

I wanted that when an operation ends all the IDisposable instances that were created and injected by Unity within that operation to be automatically disposed. Such an operation may be a request or a session in a web application, or may be a window or a view in a desktop one. In general any well-defined scope in any application.

My approach is based on using the Container Hierarchies (also known as Scoped Containers). Unity, as many other dependency containers, supports this. When you call CreateChildContainer() method, it will create a container that inherits all the configurations form the current container. The idea is that when an operation begins, a child container will be created and associated with it. During that operation all the dependency injection will be done using the child container. This means that all the new instances injected during the operation, will be created by the child container. When the operation ends, the child container will be disposed. The Dispose() of the child container should trigger the Dispose() for all IDisposable instances that were created.

Here is a good example on how to associate a child container with a web request on an ASP.NET MVC app or here for a WebApi app. I will come back in a future post on this, to show how this association can be done in a more abstract way which can also work when we are not in a web application.  Now, I will dive into how to extend to trigger the Dispose() from the child container to all the IDisposable instances that it created.

The problem to solve boils down to these:

  • Keep weak references to all the IDisposable instances that were created by the container (the child container)
  • Make sure that the Dispose() function of Unity will also call Dispose() on the instances we are referencing

The first thing I tried, was to make use of the lifetime managers. Unity defines this as an extension point to allow external code to control how references to object instances are stored and how the container disposes these instances. For example they are used to implement Singleton-like instances. When the container is configured, using RegisterType() method, an instance of a LifetimeManager has to be also given. The container will keep as part of its configuration, all the instances of the lifetime managers associated to the configured types, and it will call them when it injects instances of those types. A lifetime manager class is in general simple. It inherits the LifetimeManager base class and by overriding GetValue() and SetValue() methods, it can control the lifetime of the instances of the type it was configured with.

For example if you want that a certain type to be Singleton like, you would use the ContainerControlledLifetimeManager like this:

 container.RegisterType<IMySingletonService, MySingletonService>(
                                     new ContainerControlledLifetimeManager());

If we look into the codeof the ContainerControlledLifetimeManager we see that the lifetime manager keeps a reference to the instance and it will return it each time GetValue() is called (for simplicity I modified a bit the code of this class):

public class ContainerControlledLifetimeManager : LifetimeManager, IDisposable  
{  
    private object value;

    /// <summary>  
    /// Retrieve a value from the backing store associated with this Lifetime policy.  
    /// </summary>  
    /// <returns>the object desired, or null if no such object is currently stored.</returns>  
    public override object GetValue()  
    {  
        return this.value;  
    }

    /// <summary>  
    /// Stores the given value into backing store for retrieval later.  
    /// </summary>  
    /// <param name="newValue">The object being stored.</param>  
    public override void SetValue(object newValue)  
    {  
        this.value = newValue;  
    }

    /// <summary>  
    /// Remove the given object from backing store.  
    /// </summary>  
    public override void RemoveValue()  
    {  
        this.Dispose();  
    }

    public void Dispose()  
    {  
        this.Dispose(true);  
        GC.SuppressFinalize(this); // shut FxCop up  
    }

    protected virtual void Dispose(bool disposing)  
    {  
        if (this.value != null)  
        {  
            if (this.value is IDisposable)  
            {  
                ((IDisposable)this.value).Dispose();  
            }  
            this.value = null;  
        }  
    }  
}

The first time an instance of MySingletonClass needs to be injected, the Unity container will first call the GetValue() of the lifetime manager. If that returns null, the container will build a new instance, will call the SetValue() of the lifetime manager to pass it back, and then it will inject it further. Next time an instance of same time is needed, the GetValue() will return the previously created one, so the container will not build a new one. Therefore, the Singleton-like behavior.

The TransientLifetimeManger is at the other end. It is used when you want new instances to be created each time they need to be injected. It is also the default. Its code is even simpler because GetValue() always returns null, which makes the container to build new instances each time.

 /// <summary>  
 /// An <see cref="LifetimeManager"/> implementation that does nothing,  
 /// thus ensuring that instances are created new every time.  
 /// </summary>  
 public class TransientLifetimeManager : LifetimeManager  
 {  
     /// <summary>  
     /// Retrieve a value from the backing store associated with this Lifetime policy.  
     /// </summary>  
     /// <returns>the object desired, or null if no such object is currently stored.</returns>  
     public override object GetValue()  
     {  
         return null;  
     }

     /// <summary>  
     /// Stores the given value into backing store for retrieval later.  
     /// </summary>  
     /// <param name="newValue">The object being stored.</param>  
     public override void SetValue(object newValue)  
     {  
     }

     /// <summary>  
     /// Remove the given object from backing store.  
     /// </summary>  
     public override void RemoveValue()  
     {  
     }  
 }  

Unity design and documentation encourages using the lifetime managers to control the disposing of created instances. On its Dispose() the container will call the Dispose() on all the lifetime manager instances that implement IDisposable. However, the TransientLifetimeManger is not IDisposable. This is somehow normal because it does not keep reference to anything, so nothing to Dispose(). To achieve our goal, I have created a DisposableTransientLifetimeManger like this:

 public class DisposableTransientLifetimeManager : TransientLifetimeManager, IDisposable  
 {  
     private DisposableObjectList list = new DisposableObjectList();

     public override void SetValue(object newValue)  
     {  
         base.SetValue(newValue);

         IDisposable disposable = newValue as IDisposable;  
         if (disposable != null)  
         list.Add(disposable);  
     }

     public void Dispose()  
     {  
         list.Dispose(); // this will call Dispose() on all the objects from the list  
     }  
 }  

The SetValue() will populate a list which keeps weak references to all instances which are disposable. On Dispose() it will just dispose all the elements in the list. Simple. The ContainerControlledLifetimeManager is already IDisposable and it does dispose the instance it references. So now, if we use the disposable lifetime managers when we configure the container, all the instances which are IDisposable be disposed when the container gets disposed.

This works fine when we dispose the container that is directly configured, with the disposable lifetime managers. However, what we wanted was to configure once the main container, and then to use child containers for each operation (request) and to dispose the child containers only. The child containers, would use the configuration of the parent. The code snippet below shows this usage case:

 // configuring the main container  
 UnityContainer container = new UnityContainer();  
 container.RegisterType<IService1, Service1>(new DisposableTransientLifetimeManager());  
 container.RegisterType<IService2, Service2>(new DisposableTransientLifetimeManager());

 using (var childContainer = container.CreateChildContainer()) // child container should be associated with an operation (request)  
 {  
     // some instances created within the operation (request)  
     s11 = childContainer.Resolve<IService1>();  
     s12 = childContainer.Resolve<IService1>();

     s21 = childContainer.Resolve<IService2>();  
     s22 = childContainer.Resolve<IService2>();  
 } //childContainer.Dispose()

 AssertIsDisposed(() => s11.Disposed); //–> fail  
 AssertIsDisposed(() => s12.Disposed); //–> fail

 AssertIsDisposed(() => s21.Disposed); //–> fail  
 AssertIsDisposed(() => s22.Disposed); //–> fail  

This does not work as we expected, because when the child container is disposed it does not have any lifetime managers instances in it. This is because it uses the configuration from the parent, including the instances of the lifetime mangers given there. This is by design in Unity. If the lifetime mangers instances from the parent would not be used, we would get into short lived singletons issues. Think that you configure a certain type to be Singleton. If you get objects of it through main container you get instance1, but if you get it through a child container you would get instance2. To prevent this, the same instance of lifetime manager (the one given at RegisterType() is used by child containers too.

For our case, what we would like, is that for our disposable lifetime managers, the child container to create new instances of them and to use those to manage the lifetime of the objects it builds and injects. We can achieve this in by creating a custom Unity extension. Extensions are a more powerful way to extend the behavior of Unity and are often used in combination with the lifetime managers. As any powerful extension mechanism you can tweak the default behavior a lot, but when not used carefully you can work against the original design of the framework and create complexity. In our case we want to achieve the exact same thing as the HierarchicalLifetimeStrategy does for the HierarchicalLifetimeManager. So, I pretty much copied its code, into a new generic extension for any hierarchical lifetime manager, like this:

 public class HierarchicalLifetimeExtension<T> : UnityContainerExtension where T : LifetimeManager, new()  
 {  
     protected override void Initialize()  
     {  
         Context.Strategies.AddNew<HierarchicalLifetimeStrategy<T>>(UnityBuildStage.Lifetime);  
     }

     /// <summary>  
     /// A strategy that handles hierarchical lifetimes across a set of parent/child  
     /// containers.  
     /// </summary>  
     private class HierarchicalLifetimeStrategy<T> : BuilderStrategy  where T : LifetimeManager, new()  
     {  
         /// <summary>  
         /// Called during the chain of responsibility for a build operation. The  
         /// PreBuildUp method is called when the chain is being executed in the  
         /// forward direction.  
         /// </summary>  
         public override void PreBuildUp(IBuilderContext context)  
         {  
             IPolicyList lifetimePolicySource;

             var activeLifetime = context.PersistentPolicies.Get<ILifetimePolicy>(context.BuildKey, out lifetimePolicySource);  
             if (activeLifetime is T && !object.ReferenceEquals(lifetimePolicySource, context.PersistentPolicies)    )  
             {  
                 // came from parent, add a new lifetime manager locally  
                 var newLifetime = new T();

                 context.PersistentPolicies.Set<ILifetimePolicy>(newLifetime, context.BuildKey);  
                 context.Lifetime.Add(newLifetime);  
             }  
         }  
     }  
 }  

Now, if we put all the pieces together, we get the behavior we wanted. The snippet below shows the result.

 // configuring the main container  
 UnityContainer container = new UnityContainer();  
 container.RegisterType<IService1, Service1>(new DisposableTransientLifetimeManager());  
 container.RegisterType<IService2, Service2>(new DisposableTransientLifetimeManager());

 var outterScopeSrv = container.Resolve<IService1>();

 using (var childContainer = container.CreateChildContainer()) // child container should be associated with an operation (request)  
 {  
     // adding this extension to the child, makes the difference from previous code snippet  
     childContainer.AddExtension(  
     new HierarchicalLifetimeExtension<DisposableTransientLifetimeManager>());

     // some instances created within the operation (request)  
     s11 = childContainer.Resolve<IService1>();  
     s12 = childContainer.Resolve<IService1>();

     s21 = childContainer.Resolve<IService2>();  
     s22 = childContainer.Resolve<IService2>();  
 } //childContainer.Dispose()

 AssertIsDisposed(() => s11.Disposed); //–> success  
 AssertIsDisposed(() => s12.Disposed); //–> success

 AssertIsDisposed(() => s21.Disposed); //–> success  
 AssertIsDisposed(() => s22.Disposed); //–> success

 AssertIsNotDisposed(() => outerScopeSrv.Disposed); //–> success

So, when the child container is disposed it will call the Dispose() of all the IDisposable lifetime mangers within the child container. The DisposableTransientLifetimeManager we have created and use is IDisposable and on its Dispose() it will call the Dispose() of all the IDisposable instances that it references. The HierarchicalLifetimeExtension that we have created and added to the child container, makes sure that when an instance is to be build, for a type that was configured in the parent container, a new instance of the same lifetime manager is created and added into the child container to be used from now on when building objects of that particular type.

This approach works well for transient lifetime manager and for most of the other lifetime managers, if are extended with the IDisposable implementation in the same way. It is inline with the Unity design and not difficult to understand and use.

You can download all the source code in a zip file here.

However, this approach does not work for the PerResolveLifetimeManager. Yes, it was a bad surprise for me too :(. PerResolveLifetimeManager is not IDisposable, but that’s not the issue. We could make a DisposablePerResolveLifetimeManager as we did for the transient, and collect in it weak references to all IDisposable instances. However, the PerResolveLifetimeManager behavior is implemented with the DynamicMethodConstructorStrategy, and this is problematic. Under certain conditions this strategy creates new instances of the PerResolveLifetimeManager. This seems to work against the original design of Unity, because by creating more new instances of a lifetime manager within same container instance, the lifetime manager is striped by its main purpose, which is to control the lifetime of the instances of a particular type. Here, the used instance of the lifetime manager is no longer given through RegisterType() method, but it is being created during the object build. So, our current approach does not work for this lifetime manager for two main reasons: not all of the new instances of the PerResolveLifetimeManager get stored into the container to be disposed, and the DynamicMethodConstructorStrategy will build new instances of PerResolveLifetimeManager not of DisposablePerResolveLifetimeManager as we’d want.

For the cases when we would like to use both the PerResolveLifetimeManager and the TransientLifetimeManger I ended up making another implementation to extend Unity with same behavior of automatically disposing all the IDisposableinstances, when the child container gets disposed. I will detail it in a future post.

many examples like the above are included in my Code Design Training

Florin Coros

Read more posts by this author.