为什么不调用我的自定义调用处理程序?

时间:2014-01-06 17:37:49

标签: c# inversion-of-control unity-container unity-interception

我正在尝试了解如何在Unity中使用调用处理程序。这是我到目前为止的代码:

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

但永远不会调用TestCallHandler.Invoke,它只是直接调用Foo.Test。我错过了什么?

2 个答案:

答案 0 :(得分:3)

另一种方式是:

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

然后创建一个继承自HandlerAttribute的类并返回一个类型为ICallHandler的实例。然后将此属性添加到要拦截的方法中。如下所示:

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


Interface IFoo
{
   [MyAttribute]
   void AMethod();
}

答案 1 :(得分:2)

注册类型和处理程序,并使用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();