Archive for the ‘IOC’ category

Counting objects with Unity

April 30th, 2010

I’m using Unity for the first time on my current project (a WCF service), and the project is now fairly large with a significant amount of container configuration.  I’m taking advantage of lifetime managers to optimise object reuse, with PerThreadLifetimeManager being particularly attractive in a service – less garbage through object reuse but no locking to worry about.

I decided that it might be nice to see counts of the number of objects that Unity is creating for each type, to confirm that my lifetime configuration is optimal.  It turned out to be straightforward to do this with a Unity extension.

Here’s how the extension is used.  First, the extension is added to the container:

    var objectCounterExtension = new ObjectCounterExtension();
    container.AddExtension(objectCounterExtension);

 

At application shutdown a list of types and their associated instance counts can be output like this:

    IDictionary<Type,int> objectCounts = objectCounterExtension.ObjectCounts;

    foreach (var objectCount in objectCounts.OrderBy(oc => oc.Value))
    {
        Type type = objectCount.Key;
        int count = objectCount.Value;
        Console.WriteLine("{0}: {1}", type, count);
    }

 

The extension is quite simple, once you know how:

    class ObjectCounterExtension : UnityContainerExtension
    {
        ObjectCounterStrategy objectCounterStrategy;

        protected override void Initialize()
        {
            objectCounterStrategy = new ObjectCounterStrategy();
            Context.Strategies.Add(objectCounterStrategy, UnityBuildStage.Creation);
        }

        public IDictionary<Type, int> ObjectCounts
        {
            get { return objectCounterStrategy.ObjectCounts; }
        }
    }

    class ObjectCounterStrategy : IBuilderStrategy
    {
        Dictionary<Type, int> objectCounts = new Dictionary<Type,int>();

        public void PostBuildUp(IBuilderContext context)
        {
            IBuildKey buildKey = context.BuildKey as IBuildKey;
            if (buildKey == null)
                return;

            Type type = buildKey.Type;

            lock (objectCounts)
            {
                int count;
                if (objectCounts.TryGetValue(type, out count))
                {
                    objectCounts[type] = count + 1;
                }
                else
                {
                    objectCounts[type] = 1;
                }
            }
        }

        public Dictionary<Type, int> ObjectCounts
        {
            get
            {
                lock (objectCounts)
                {
                    return new Dictionary<Type, int>(objectCounts);
                }
            }
        }

        public void PostTearDown(IBuilderContext context) {}
        public void PreBuildUp(IBuilderContext context) {}
        public void PreTearDown(IBuilderContext context) {}
    }
 

Unity and primitive constructor arguments

November 10th, 2009

I’m using the Unity IoC container for the first time, and overall I like it.  But one under-documented and slightly unintuitive area caused me some trouble.

Suppose I have a ThreadPool class:

class ThreadPool
{
   public ThreadPool(int maxThreads)
   {
      ...
   }
}

I can register this in the container as follows:

container.RegisterType<ThreadPool>(new InjectionConstructor(20));

So every time the container creates an instance of ThreadPool, it will pass 20 for the maxThreads argument.   It’s not the most intuitive API, but it does the job.

However suppose I now extend my ThreadPool class to add logging, i.e.:

class ThreadPool
{
   public ThreadPool(int maxThreads, ILogger logger)
   {
      ...
   }
}

How do I modify my container registration to inject the correct ILogger instance?  Of course I could just create a Logger instance and pass it as an extra argument to InjectorConstructor, but that’s not the behaviour I want.   I want the container to resolve ILogger when the ThreadPool instance is being resolved.   Having looked through the documentation, I was coming to the conclusion that this wasn’t possible, but then I came across this post on pnpguidance.net that shows how it’s done:

container.RegisterType<ThreadPool>(new InjectionConstructor(20,typeof(ILogger)));

I suppose using typeof in this scenario makes some sense, but it’s hardly intuitive.  The API could be improved so that I don’t need to specify anything about ILogger resolution at all.   I should only have to specify explicitly the constructor arguments that cannot be resolved automatically, e.g.:

container.RegisterType<ThreadPool>().WithConstructorArg("maxThreads", 20);