Unity拦截基于方法注释的更改调用处理程序

时间:2012-10-03 21:13:32

标签: c# unity-container aop interceptor

我在类中有一个方法,我想拦截:

[CustomTag1(Order = 0)]
[CustomTag2(Order = 1)]
public virtual DoSomething()

使用ICallHandler.Order时,如何将订单值注入CustomAttributeMatchingRule属性?

我不希望将订单硬编码到处理程序本身或注册时。我希望它是方法注释的Order属性的变量。

1 个答案:

答案 0 :(得分:5)

我已经使用HandlerAttribute实现了这一点 - 通常我在Unity中使用它来进行属性样式拦截只是因为你不必手动创建策略 - 而只是将HandlerAttribute应用于你的代码而Unity将会自动为您创建政策。

无论如何,这样的事情可能就是你所追求的。首先像往常一样定义一个调用处理程序,除了参数化它: -

public class MyCallHandler : ICallHandler
{
    public MyCallHandler(Int32 value)
    {
        Order = value;
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        Console.WriteLine("Parameterised call handler!");
        return getNext()(input, getNext);
    }

    public int Order { get; set; }
}

现在不使用CustomTagAttribute,而是使用HandlerAttribute: -

public class MyHandler : HandlerAttribute
{
    private readonly Int32 value;
    public MyHandler(Int32 value)
    {
        this.value = value;
    }

    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new MyCallHandler(value);
    }
}

MyHandler适用于您的课程。调用CreateHandler方法,此时它创建一个实例MyCallHandler: -

public class MyClass
{
    [MyHandler(2)] // Order of 2
    public virtual void Foo()
    {
        Console.WriteLine("Inside method!");
    }
}

请注意,我故意将这两个类分开,但实际上你只需要一个类实现ICallHandler接口和HandlerAttribute抽象方法(只需返回“this”)。

你可以在没有HandlerAttribute的情况下使用你自己的自定义属性来实现类似的东西,但它可以节省你的时间,因为你不需要乱搞你自己的策略。

有一点需要注意 - 如果采用参数化方法,则不能将调用处理程序作为单例,因为每次都会创建一个不同的实例,具体取决于您希望它的顺序。