PerResolveLifetimeManager + Custom Interception

Jun 16, 2010 at 11:32 PM

Hey,

 

I'm trying to implement my own interception while still using the Unity container.  I want to do this in such a way where it respects the lifetime manager used.  i.e. if it is a PerResolveLifetimeManager then I want to have wrap the instance once and I want that wrapped instance to be used throughout the resolve. 

So far I implemented a BuilderStrategy that I add to my container using a custom UnityContainerExtension class (I pass PostInitialization to the AddNew method; I'm not sure what the most appropriate value is but this seemed to work).  In a PostBuildUp override in my BuilderStrategy, I replace context.Existing with my wrapped value.

This seems to be working well for the default and ContainerControlled lifetimes -- the wrapping occurs the expected number of times and the wrapped instances are passed around as expected.  However, for the PerResolve lifetime, one wrap occurs but only the first use of the dependency gets the wrapped instance and the rest get a non wrapped instance.  i.e. if my ctor takes in IFoo foo1 and IFoo foo2  then only foo1 is my wrapped instance whileas foo2 is the unwrapped instance.

Here is a sample repro (for simplicity, I am using an instance of another class, Foo2, instead of wrapping):

    public class MyInterception : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Context.Strategies.AddNew<MyInterceptionStrategy>(UnityBuildStage.PostInitialization);
        }
    }

    public class MyInterceptionStrategy : BuilderStrategy
    {
        public override void PostBuildUp(IBuilderContext context)
        {
            if (!context.OriginalBuildKey.Type.IsInterface)
            {
                return;
            }

            context.Existing = new Foo2();
        }
    }

    public class Bar
    {
        public Bar(IFoo f1, IFoo f2, IFoo f3)
        {
        }
    }

    public interface IFoo
    {
    }

    public class Foo1 : IFoo
    {
    }

    public class Foo2 : IFoo
    {
    }

    public void Main()
    {
        UnityContainer container = new UnityContainer();
        container.AddNewExtension<MyInterception>();
        container.RegisterType(typeof (IFoo), typeof (Foo1), new PerResolveLifetimeManager());

        container.Resolve<Bar>();
    }

If you put a breakpoint in PostBuildUp and in Bar's contructor and debug Main up through the resolve of Bar, you can see that PostBuildUp is only called once.  However, in Bar's constructor, f1 is an instance of Foo2 (a "wrapped" instance) whileas f2 and f3 are instances of Foo1 (unwrapped). 

I was wondering if what I want is possible and if I am taking the right approach?  Are my problems related to lifetimes and/or the UnityBuildStage that I added the BuilderStrategy for?

Thanks