c# – 使用深度继承树拦截对象

我有对象结构,继承深度为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
      }
}

对象注册到Unity容器中,如下所示:

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

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

不幸的是,我的拦截器总是只为ExecuteMyCommand()方法调用.是否有可能通过统一容器进行此类拦截?我正在慢慢想通过Spring.NET AOP库来实现它.

最佳答案 首先,我建议你尽可能使用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*/ }
}

这些选项对你有用吗?

点赞