0

我有 3 个属性用于 Unity v2.1 中的 Inteception 管道。一切都正常启动,只是顺序错误。

在所有 3 个属性中,我确保我从属性传递了相应的处理程序。

因此,如果我在下面的 TestClass.TestProperty 上调用 setter,我希望调用处理程序应按以下顺序调用:Validation、Transaction、Notify。我看到的是Notify, Transaction, Validation

我在这里有 2 个问题,我无法找到使用谷歌搜索的答案。

  1. 在我设置 TestClass.TestProperty 的示例中,是否假设先调用属性属性然后调用类属性?还是 Unity 应该尊重我的命令?
  2. 如果首先调用 2 个属性处理程序,我应该看不到Notify, Transaction。如果我覆盖 Transaction 和 Notify Order 的默认值分别为 1 和 2,我会得到Transaction, Notify的预期。我的订单从 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;
        }
    }
    
4

1 回答 1

0

对我来说,它似乎以正确的顺序启动。这是我的示例代码:

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

我将 TestProperty 属性设为虚拟,因此我可以使用 VirtualMethodInterceptor。这是注册和测试代码:

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

当我运行此代码时,我看到:

验证!
交易!
通知!

如果我将 ValidationAttribute 构造函数的 order 参数更改为 9 ( [Validation(9)]),那么我会看到 Validation 按预期最后发生。

于 2013-10-17T01:19:34.223 回答