使用深度继承树拦截对象
本文关键字:对象 继承 深度 | 更新日期: 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*/ }
}
这些选项中的任何一个都适合您?