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.
First off, I would recommend you use the InterfaceInterceptor wherever possible. It will give you the best flexibility and performance. Fall back to using VirtualMethodInterceptor when you can't use InterfaceInterceptor. And as a last resort, use TransparentProxyInterceptor. See here.
For interfaces, the handler attribute only applies to the methods defined on that interface (not inherited). So you can achieve what you are after by decorating all 4 interfaces with the [MyHandler] attribute.
For concrete classes, the handler attribute applies to all inherited types. So you can achieve what you are after by decorating the top AbstractSerialDevice with the [MyHandler] attribute. You could also decorate individual methods on either the interface or the concrete class level.
Also, in my opinion, decorating a concrete method is a bit more discoverable than decorating a type. Though it is a bit more verbose.
Option 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 */ }
Option 2
// No MyHandler on any of the interfaces nor derived classes
[MyHandler]
public abstract class AbstractSerialDevice : ISerialDevice
{ /* omitted */ }
Option 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*/ }
}
Any of those options work for you?