3

Я пытаюсь понять, как использовать обработчики вызовов с 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

Зарегистрируйте как тип, так и обработчик и добавьте перехватчик с 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(); 
+0

Спасибо! Это действительно решает проблему. Я думал, что это можно сделать глобально для всех типов. –

+0

Документ MSDN предупреждает, что TransparentProxyInterceptor работает очень медленно. Рекомендуется использовать InterfaceInterceptor. https://msdn.microsoft.com/en-us/library/dn178466(v=pandp.30).aspx#sec9 – Calvin

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.Then добавить этот атрибут к способу intercept.Something, как это:

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


Interface IFoo 
{ 
    [MyAttribute] 
    void AMethod(); 
} 
Смежные вопросы