Policy Injection in child container in 2.0

May 6, 2011 at 10:45 PM

Hi,

I'm migrating from Unity 1.2 to 2.0 and I'm seeing a difference in the way policy injection works in Unity 2.0. When resolving through the child container, there are twice as many call handlers in the interception pipeline as I was expecting. Am I doing something wrong or is this the expected behavior? Here's a simple console app that demonstrates this. The console output is

parent
Hello
parent
child
parent
child
Hello

whereas I was expecting

parent
Hello
parent
child
Hello

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using System.Collections.Specialized;

namespace UnityTest
{
    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer parentContainer = new UnityContainer();
            parentContainer.AddNewExtension<Interception>();
            
            parentContainer.RegisterType<ITest, Test>(
                new Interceptor<VirtualMethodInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>());

            parentContainer.Configure<Interception>()
                .AddPolicy("test")
                .AddMatchingRule<TagAttributeMatchingRule>(new InjectionConstructor("Test", true))
                .AddCallHandler<TestCallHandler>(new InjectionConstructor("parent"));

            IUnityContainer childContainer = parentContainer.CreateChildContainer();
            childContainer.AddNewExtension<Interception>();
            childContainer.Configure<Interception>()
                .AddPolicy("test2")
                .AddMatchingRule<TagAttributeMatchingRule>(new InjectionConstructor("Test", true))
                .AddCallHandler<TestCallHandler>(new InjectionConstructor("child"));

            ITest parentObject = parentContainer.Resolve<ITest>();
            parentObject.Hello();

            ITest testObject = childContainer.Resolve<ITest>();
            testObject.Hello();
        }
    }

    public interface ITest
    {
        void Hello();
    }

    public class Test : ITest
    {
        [Tag("Test")]
        public virtual void Hello()
        {
            Console.WriteLine("Hello");
        }
    }
    
    public class TestCallHandler : ICallHandler
    {
        private string message;

        public TestCallHandler(string message)
        {
            this.message = message;
        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            Console.WriteLine(message);
            IMethodReturn result = getNext()(input, getNext);
            return result;
        }

        public int Order
        {
            get;
            set;
        }
    }


}

 


May 8, 2011 at 1:24 PM

Hi,

Try registering your objects using InterfaceInterceptor instead.

            parentContainer.RegisterType<ITest, Test>(
                new Interceptor<InterfaceInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>());

Unfortunately, I'm a bit surprise myself why the VirtualMethodInterceptor is behaving like what you have observed and still looking up for some clues about it.

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

May 13, 2011 at 4:57 PM

Does the inconsitency between the VirtualMethodInterceptor and InterfaceInterceptor suggest that this is a bug?

May 18, 2011 at 10:15 AM

Hi,

I believe this is not a bug. Since you are resolving an interface mapped to a type, its appropriate to use the InterfaceInterceptor as already mentioned in http://msdn.microsoft.com/en-us/library/ff660861(v=PandP.20).aspx#_Comparison_of_Interception. Hope this helps.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com