Unity: Зарегистрируйте два интерфейса как один синглтон с перехватом

У меня есть класс, реализующий два интерфейса, и я хочу применить перехват к методам класса.

I Следую совету Unity Зарегистрируйте два интерфейса как один синглтон , но результаты меня удивили. Короче, кажется, что мой CallHandler вызывается дважды. Самый короткий пример, который у меня есть:

public interface I1
{
    void Method1();
}

public interface I2
{
    void Method2();
}

public class C : I1, I2
{
    [Log]
    public void Method1() {}

    public void Method2() {}
}

public class LogAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogCallHandler();
    }
}

public class LogCallHandler : ICallHandler
{
    public IMethodReturn Invoke(
        IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        Console.WriteLine("Entering " + input.MethodBase.Name);
        var methodReturn = getNext().Invoke(input, getNext);
        Console.WriteLine("Leaving " + input.MethodBase.Name);
        return methodReturn;
    }

    public int Order { get; set; }
} 

void Test()
{
    IUnityContainer container = new UnityContainer();
    container.AddNewExtension();
    container.RegisterType(new ContainerControlledLifetimeManager());

    container.RegisterType(
        new Interceptor(),
        new InterceptionBehavior());

    container.RegisterType(
        new Interceptor(),
        new InterceptionBehavior());

    container.Resolve().Method1();
}

Что дает следующий результат:

Entering Method1
Entering Method1
Leaving Method1
Leaving Method1

Удаление строки «container.RegisterType I2, C» приводит к тому, что журнал появляется только один раз. Добавление третьего интерфейса, I3, который похож на I2, приводит к тому, что журнал появляется три раза.

Я ожидал, что журнал будет вызываться только один раз. Я, вероятно, смогу добиться этого, если LogCallHandler определит, вызывается ли он из другого LogCallHandler, но это кажется неэлегантным.

Первоначально я хотел применить поведение перехвата к C, а не к I1 и I2 по отдельности, но это требует, чтобы C наследовал из MarshalByRefObject, что является ограничением, которое я пока не хочу налагать.

Есть ли альтернативный способ?

6
задан Community 23 May 2017 в 12:07
поделиться