4

I'm having object structure with depth of inheritance of 3. Object is implementing single particular interface. The depth of inheritance for interface is 4. My final object is being constructed via unity IoC. I need to intercept every public method in this object (means no matter in which of interfaces it is defined), though whatever interceptor type I use (InterfaceInterceptor/TransparentProxyInterceptor/VirtualMethodInterceptor ) it always intercepts only methods defined in the final class of inheritance tree. Please see the illustration of object structure below:

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
      }
}

Object is registered into unity container as follows:

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

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

Unfortunately my interceptor always gets invoked only for ExecuteMyCommand() method. Is it possible to do such interception I'm striving for via unity container? I'm slowly thinking of trying to achieve it via Spring.NET AOP library.

4

1 回答 1

2

首先,我建议您尽可能使用 InterfaceInterceptor。它将为您提供最佳的灵活性和性能。当您无法使用 InterfaceInterceptor 时,回退到使用 VirtualMethodInterceptor。作为最后的手段,使用透明代理拦截器。见这里

对于接口,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*/ }
}

这些选项中的任何一个对您有用吗?

于 2014-12-21T04:18:04.920 回答