Archive for the ‘Unity’ 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’s VirtualMethodInterceptor with internal classes

December 13th, 2009

Unity includes some basic AOP functionality.  One of the interception mechanisms it offers is VirtualMethodInterceptor, which works by building a derived class at runtime and overriding the virtual methods of the target class.  This approach has some obvious limitations, but it seemed like a good way to handle some simple logging & profiling requirements that I have with my current project.

The first problem I hit is that the current release of Unity (1.2) has a huge bug – VirtualMethodInterceptor doesn’t work with classes that have parameters in their constructors.  Fortunately downloading and building the latest source was enough to get around that problem.

The next problem is that VirtualMethodInterceptor requires the target class to be public.  This is a common problem with code that builds derived classes at runtime.  Moq has the same issue, for example.  The standard workaround is to use the InternalsVisibleTo assembly attribute to give the dynamic assembly access to internal classes in the target assembly.   So after a little digging in the source I found the name of the dynamic assembly, and added this to my assembly:

[assembly: InternalsVisibleTo("Unity_ILEmit_DynamicClasses")]

Unfortunately this is not sufficient.  The Unity code has some validation that insists on the target class being public.  The code is in VirtualMethodInterceptor.cs:

public bool CanIntercept(Type t)
{
    Guard.ArgumentNotNull(t, "t");
    return t.IsClass &&
        (t.IsPublic || t.IsNestedPublic) &&
        t.IsVisible &&
        !t.IsSealed;
}

Removing the checks for IsPublic and IsVisible was enough to finally get everything to work correctly:

public bool CanIntercept(Type t)
{
    Guard.ArgumentNotNull(t, "t");
    return t.IsClass && !t.IsSealed;
}

Hopefully this will be fixed in time for the release of Unity 2.0.

Update: For internal interfaces with InterfaceInterceptor, you need this:

[assembly: InternalsVisibleTo("Unity_ILEmit_InterfaceProxies")]

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);