I have a class that implements two interfaces, and I want to apply interception to class methods.
I follow the tips in Unity Register two interfaces as one singleton , but I am surprised by the results. In a nutshell, it seems that my CallHandler is being called twice. The shortest example:
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<Interception>(); container.RegisterType<C>(new ContainerControlledLifetimeManager()); container.RegisterType<I1, C>( new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>()); container.RegisterType<I2, C>( new Interceptor<TransparentProxyInterceptor>(), new InterceptionBehavior<PolicyInjectionBehavior>()); container.Resolve<I1>().Method1(); }
What gives this conclusion:
Entering Method1 Entering Method1 Leaving Method1 Leaving Method1
Removing the string "container.RegisterType I2, C" makes the log appear only once. Adding a third interface, I3, which is similar to I2, makes the log appear three times.
I would expect Log to be called only once. Perhaps I can achieve this by discovering that the LogCallHandler detects whether it is called from another LogCallHandler, but that seems inelegant.
Initially, I wanted to apply the interception behavior to C, and not to I1 and I2 separately, but this requires C to inherit from MarshalByRefObject, which is a constraint that I do not want to impose.
Is there an alternative way?
c # unity-container unity-interception
hibernator
source share