2 つのインターフェイスを実装するクラスがあり、クラスのメソッドにインターセプトを適用したいと考えています。
Unity Register two interfaces as one singletonのアドバイスに従っていますが、結果には驚いています。一言で言えば、私の CallHandler が 2 回呼び出されているようです。私が持っている最短の例はこれです:
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();
}
次の出力が得られます。
Entering Method1
Entering Method1
Leaving Method1
Leaving Method1
「container.RegisterType I2, C」行を削除すると、ログが 1 回だけ表示されます。I2 に似た 3 番目のインターフェイス I3 を追加すると、ログが 3 回表示されます。
Log が 1 回だけ呼び出されることを期待していました。LogCallHandler が別の LogCallHandler から呼び出されているかどうかを検出することでおそらくこれを達成できますが、これは洗練されていないようです。
もともと、インターセプト動作を I1 と I2 に個別に適用するのではなく、C に適用したかったのですが、これには C が MarshalByRefObject から継承する必要があり、これはまだ課したくない制約です。
別の方法はありますか?