Archive for April, 2010

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) {}
    }