Reputation: 23
I have 3 attributes I am using for my Inteception pipeline in Unity v2.1. Everything is firing off properly they are just in the wrong order.
In all 3 Attributes I have made sure I am passing the corresponding Handler the Order from the attribute.
So if I call the setter on the TestClass.TestProperty below I am expecting that the call handlers should be called in this order: Validation, Transaction, Notify. What I am seeing is Notify, Transaction, Validation.
I have 2 questions here that I can't find answers to using googling around.
If the 2 property handlers are called first should I not see Notify, Transaction. If I override the Transaction and Notify Order defaults to 1 and 2 respectively I get Transaction, Notify as expected. Should it matter that my order start at 1.
[AttributeUsage(AttributeTargets.Class)
public class ValidationAttribute : HandlerAttribute
{
public ValidationAttribute(int order = 1)
{
Order = order
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
var ValidationHandler = container.Resolve<ValidationHandler>();
ValidationHandler.Order = Order;
}
}
public class TransactionAttribute : HandlerAttribute
{
public TransactionAttribute (int order = 2)
{
Order = order
}
// Same CreateHandler as above resolving correct handler
}
public class NotifyAttribute : HandlerAttribute
{
public NotifyAttribute (int order = 3)
{
Order = order
}
// Same CreateHandler as above resolving correct handler
}
// Didn't include handler code to keep short(ish). All handlers have logging to show they are executing
...
[Validation]
public class TestClass
{
public int TestProperty
{
get;
[Transaction]
[Notify]
set;
}
}
Upvotes: 0
Views: 773
Reputation: 22655
It seems to be firing off in the correct order for me. Here is my sample code:
[AttributeUsage(AttributeTargets.Class)]
public class ValidationAttribute : HandlerAttribute
{
public ValidationAttribute(int order = 1)
{
Order = order;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
var handler = container.Resolve<ValidationHandler>();
handler.Order = Order;
return handler;
}
}
public class TransactionAttribute : HandlerAttribute
{
public TransactionAttribute(int order = 2)
{
Order = order;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
var handler = container.Resolve<TransactionHandler>();
handler.Order = Order;
return handler;
}
}
public class NotifyAttribute : HandlerAttribute
{
public NotifyAttribute(int order = 3)
{
Order = order;
}
public override ICallHandler CreateHandler(IUnityContainer container)
{
var handler = container.Resolve<NotifyHandler>();
handler.Order = Order;
return handler;
}
}
public class ValidationHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("Validation!");
return getNext().Invoke(input, getNext);
}
public int Order
{
get;
set;
}
}
public class TransactionHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("Transaction!");
return getNext().Invoke(input, getNext);
}
public int Order
{
get;
set;
}
}
public class NotifyHandler : ICallHandler
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("Notify!");
return getNext().Invoke(input, getNext);
}
public int Order
{
get;
set;
}
}
[Validation]
public class TestClass
{
public virtual int TestProperty
{
get;
[Transaction]
[Notify]
set;
}
}
I made the TestProperty property virtual so I could use the VirtualMethodInterceptor. Here is the registration and test code:
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<ValidationHandler>(new ContainerControlledLifetimeManager());
container.RegisterType<TransactionHandler>(new ContainerControlledLifetimeManager());
container.RegisterType<NotifyHandler>(new ContainerControlledLifetimeManager());
container.RegisterType<TestClass>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<VirtualMethodInterceptor>());
var testClass = container.Resolve<TestClass>();
testClass.TestProperty = 5;
}
}
When I run this code I see:
Validation!
Transaction!
Notify!
If I change the order argument to the ValidationAttribute constructor to 9 ([Validation(9)]
) then I see Validation happening last as expected.
Upvotes: 0