使用深度继承树拦截对象

时间:2014-12-20 18:01:42

标签: c# unity-container aop unity-interception

我的对象结构具有3的继承深度。对象正在实现单个特定的接口。接口的继承深度为4.我的最终对象是通过统一IoC构建的。我需要拦截此对象中的每个公共方法(意味着无论在哪个接口中定义),尽管我使用的任何拦截器类型(InterfaceInterceptor / TransparentProxyInterceptor / VirtualMethodInterceptor)它始终只拦截继承树的最终类中定义的方法。请参阅下面的对象结构图示:

public interface IDevice {
    void Connect();
}

public interface ISerialDevice {
   void WriteCommand();
}

public interface IProtocolSerialDevice {
   void ExecuteProtocolCommand();
}

[MyHandler]
public interface ICustomSerialDevice {
   void ExecuteMyCommand();
}

public abstract class AbstractSerialDevice {
   public virtual void WriteCommand() {
        //omitted
   }
}

public abstract class AbstractProtocolSerialDevice : AbstractSerialDevice {
    public virtual void ExecuteProtocolCommand() {
         //omitted
    }
}


public class CustomSerialDevice : AbstractProtocolSerialDevice, ICustomSerialDevice {
      public virtual void ExecuteMyCommand() {
            //omitted
      }
}

public class MyHandlerAttribute : HandlerAttribute {
      public override ICallHandler CreateHandler(IUnityContainer container) {
         //omitted
      }
}

对象按如下方式注册到统一容器中:

container.RegisterType<ICustomSerialDevice, CustomSerialDevice>(
   new ContainerControlledLifetimeManager(),  new InjectionMethod(postConstructMethodName));

container.Configure<Interception>()
         .SetInterceptorFor<ICustomSerialDevice>(new TransparentProxyInterceptor());

不幸的是,我的拦截器总是只为ExecuteMyCommand()方法调用。是否有可能进行这样的拦截我是否正在努力通过统一集装箱?我正在慢慢想通过Spring.NET AOP库来实现它。

1 个答案:

答案 0 :(得分:2)

首先,我建议您尽可能使用InterfaceInterceptor。它将为您提供最佳的灵活性和性能。当您不能使用InterfaceInterceptor时,回退到使用VirtualMethodInterceptor。作为最后的手段,使用TransparentProxyInterceptor。请参阅here

对于接口,handler属性仅适用于在该接口上定义的方法(不是继承的)。因此,您可以通过使用[MyHandler]属性装饰所有4个接口来实现您的目标。

对于具体类,handler属性适用于所有继承的类型。因此,您可以通过使用[MyHandler]属性装饰顶部AbstractSerialDevice来实现您的目标。您还可以在接口或具体类级别上修饰单个方法。

另外,在我看来,装饰具体方法比装​​饰类型更容易被发现。虽然它有点冗长。


选项1

// No MyHandler on any of the concrete classes

[MyHandler]
public interface IDevice
{ /* omitted */ }

[MyHandler]
public interface ISerialDevice : IDevice
{ /* omitted */ }

[MyHandler]
public interface IProtocolSerialDevice : ISerialDevice
{ /* omitted */ }

[MyHandler]
public interface ICustomSerialDevice : IProtocolSerialDevice
{ /* omitted */ }

选项2

// No MyHandler on any of the interfaces nor derived classes

[MyHandler]
public abstract class AbstractSerialDevice : ISerialDevice
{ /* omitted */ }

选项3

// No MyHandler on any of the interfaces nor abstract classes

public class CustomSerialDevice : AbstractProtocolSerialDevice, ICustomSerialDevice
{
    [MyHandler]
    public override void Connect()
    { base.Connect(); }

    [MyHandler]
    public override void WriteCommand()
    { base.WriteCommand(); }

    [MyHandler]
    public override void ExecuteProtocolCommand()
    { base.ExecuteProtocolCommand(); }

    [MyHandler]
    public void ExecuteMyCommand()
    { /*omitted*/ }
}

这些选项对你有用吗?