使用深度继承树拦截对象

本文关键字:对象 继承 深度 | 更新日期: 2023-09-27 18:35:00

我的对象结构继承深度为 3。对象正在实现单个特定接口。接口的继承深度为 4。我的最终对象是通过 Unity 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()方法调用。是否有可能通过 Unity 容器进行我正在努力的拦截?我正在慢慢考虑尝试通过 Spring.NET AOP库来实现它。

使用深度继承树拦截对象

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

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

对于具体类,处理程序属性适用于所有继承的类型。 因此,您可以通过使用 [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*/ }
}

这些选项中的任何一个都适合您?