У меня есть класс, реализующий два интерфейса, и я хочу применить перехват к методам класса.
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, что является ограничением, которое я пока не хочу налагать.
Есть ли альтернативный способ?