The Resolvable

December 21st, 2008

I wrote a post last week about a memory leak i had introduced in my code due to not properly releasing resolved components through the Windsor IoC container. I wanted to try to make sure that i’d never make that mistake again and this is the approach i came up with.

If you’re using an IOC container it’s important to not use it all over the place. You basically use it in as few places as possible to resolve a component and you let the container sort out all of the dependencies. So in the few places where you use the container directly, you need to resolve the component, and in case of transient components you also need to release them through the container. Releasing it is very easy to forget, so i wanted something that would guarantee that the component would be properly released. Enter the Resolvable class:

    public class Resolvable<T> : Disposable

    {

        private readonly T instance;

 

        public Resolvable() : this(null) {}

 

        public Resolvable(object argumentsAsAnonymousType)

        {

            if (argumentsAsAnonymousType == null)

            {

                instance = IoC.Container.Resolve<T>();

            }

            else

            {

                instance = IoC.Container.Resolve<T>(argumentsAsAnonymousType);

            }

        }

 

        public T Instance

        {

            get { return instance; }

        }

 

        protected override void DisposeManagedResources()

        {

            IoC.Container.Release(instance);

        }

    }

The Resolvable class inherits from my Disposable class, so the Disposable pattern is correctly implemented.

From now on, instead of calling the container directly, i just instantiate a new Resolvable in a using block. Let’s try it out.

I’m reusing my test component with a dependency from one of the previous posts:

    public interface IDependency : IDisposable

    {

        bool Disposed { get; set; }

    }

 

    public class MyDependency : IDependency

    {

        public bool Disposed { get; set; }

 

        public void Dispose()

        {

            Disposed = true;

        }

    }

 

    public interface IController : IDisposable

    {

        bool Disposed { get; set; }

        IDependency Dependency { get; }

    }

 

    public class Controller : IController

    {

        public IDependency Dependency { get; private set; }

 

        public Controller(IDependency myDependency)

        {

            Dependency = myDependency;

        }

 

        public void Dispose()

        {

            Dependency.Dispose();

            Disposed = true;

        }

 

        public bool Disposed { get; set; }

    }

Now, instead of resolving an IController directly through the container and having to dispose of it, i just do this:

        [Test]

        public void ResolvableInstanceIsProperlyReleasedAfterDisposal()

        {

            IoC.Container.Register(Component.For<IController>().ImplementedBy<Controller>().LifeStyle.Transient);

            IoC.Container.Register(Component.For<IDependency>().ImplementedBy<MyDependency>().LifeStyle.Transient);

 

            IController controller;

            IDependency dependency;

 

            using (var resolvable = new Resolvable<IController>())

            {

                controller = resolvable.Instance;

                dependency = controller.Dependency;

            }

 

            Assert.IsTrue(controller.Disposed);

            Assert.IsTrue(dependency.Disposed);

            Assert.IsFalse(IoC.Container.Kernel.ReleasePolicy.HasTrack(controller));

            Assert.IsFalse(IoC.Container.Kernel.ReleasePolicy.HasTrack(dependency));

        }

The container doesn’t hold the reference to the instance, and both the instance and its dependency is properly disposed.

Guest Blogger

  • http://www.elegantcode.com Jarod Ferguson

    Pretty Cool Davy. I was hanging out with Glenn Block at Kaizen and he wrote something very similar which he called IResolver. He was solving a different problem in that you dont always have the luxury of, or want, a container reference, but the pattern is exactly the same. I really like how you have used it to solve the disposable problem you have been posting about.

  • http://elegantcode.com Davy Brion

    Thanks… i just love ‘abusing’ the using block to prevent mistakes. i have another example here:
    http://davybrion.com/blog/2008/05/easy-non-blocking-locking/

  • http://jonathan-oliver.blogspot.com Jonathan

    You may want to seriously consider looking at Autofac, an IoC container which handles disposals. It does this by tracking much the same way you are above but without all the custom code.

  • http://elegantcode.com Davy Brion

    Autofac uses nested containers to handle it… not really a fan of that approach.

  • http://www.elegantcode.com Jarod Ferguson

    Autofac is pretty cool, though changing Containers is usually not an option once development is full swing.

    The nested container approach doesn’t bother me actually, it has some good benefits. I think MEF is going to do the same. In fact, I think the AutoFac guy is on the MEF team?

  • http://elegantcode.com Davy Brion

    dunno about any of the Autofac guys being on the MEF team, but Hammett (from Castle Windsor) is on the team though

  • http://www.elegantcode.com Jarod Ferguson
  • http://elegantcode.com/2008/12/30/the-injected-context/ Elegant Code » The Injected Context

    [...] Nicholas points out some of the issues with a traditional approach of a static global container (Fragility, Reduced Composability, Limited Reuse and Resumption of Control). These are issues which I have seen peers solve repeatedly as of late by delegating resolution though a provider/proxy interface like IResolver<T> or Resolvable<T>. [...]

blog comments powered by Disqus