3

I'm trying to understand how to use call handlers with Unity. Here's the code I have so far:

void Main()
{
    var container = new UnityContainer();
    container.AddNewExtension<Interception>()
             .Configure<Interception>()
             .AddPolicy("TestPolicy")
             .AddCallHandler(new TestCallHandler());
    container.RegisterType<IFoo, Foo>();
    var foo = container.Resolve<IFoo>();
    foo.Test();
}

interface IFoo
{
    void Test();
}

class Foo : IFoo
{
    public void Test()
    {
        "Foo.Test()".Dump();
    }
}

class TestCallHandler : ICallHandler
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate  getNext)
    {
        Console.WriteLine("[Interceptor] Calling {0}.{1}", input.MethodBase.DeclaringType.FullName, input.MethodBase.Name);
        return getNext()(input, getNext);
    }

    public int Order { get; set; }
}

But TestCallHandler.Invoke is never called, it just calls Foo.Test directly. What am I missing?

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758

2 Answers2

3

The other way is:

var container = new UnityContainer();
container.AddNewExtension<Interception>()
         .RegisterType<IFoo, Foo>()
         .Configure<Interception>()
         .SetInterceptorFor<IFoo>(new InterfaceInterceptor());
var foo = container.Resolve<IFoo>();
foo.Test();

And you create a class that inherits from HandlerAttribute and return an instance of type ICallHandler.Then add this attribute to the method to intercept.Something like this:

class MyAttribute : HandlerAttribute
{
   override ICallHandler CreateHandler(IUnityContainer container)
   {
       return new TestCallHandler();
   }
}


Interface IFoo
{
   [MyAttribute]
   void AMethod();
}
Amit Kumar Ghosh
  • 3,618
  • 1
  • 20
  • 24
2

Register both the type and the handler and add an interceptor with a PolicyInjectionBehavior.

var container = new UnityContainer();
container.AddNewExtension<Interception>()
         .RegisterType<TesCallHandler>()
         .RegisterType<IFoo, Foo>(new Interceptor<TransparentProxyInterceptor>(),
             new InterceptionBehavior<PolicyInjectionBehavior>())
         .Configure<Interception>()
         .AddPolicy("TestPolicy")
         .AddCallHandler(new TestCallHandler());
var foo = container.Resolve<IFoo>();
foo.Test();
mockinterface
  • 14,452
  • 5
  • 28
  • 49
  • Thanks! It does indeed solve the problem. I thought it was possible to do it globally for all types. – Thomas Levesque Jan 07 '14 at 09:35
  • MSDN document warns that TransparentProxyInterceptor is very slow. InterfaceInterceptor is recommended. https://msdn.microsoft.com/en-us/library/dn178466(v=pandp.30).aspx#sec9 – Calvin Feb 27 '15 at 22:37