编程语言
首页 > 编程语言> > c# – 如何使用Ninject设置可选方法拦截?

c# – 如何使用Ninject设置可选方法拦截?

作者:互联网

假设我有一个类,我希望有时*(但现在总是)拦截一些(但不是全部)方法.我理解它的方式,可以使用我的Ninject模块中的InterceptAround()(在更高级别的代码中),或者使用这些方法上的InterceptAttribute派生属性(在实现级别)来完成.

我真的不喜欢第一种方式,因为它需要消费者知道细节,有很多类有很多方法.但我也不喜欢第二种方式,因为我没有看到如何禁用(或者更确切地说,不启用)拦截,因为属性与代码融合.

有没有一些已知的方法来解决这个问题?

*:适用于应用程序的生命周期.

解决方法:

听起来好像你指的是一个普通的动态拦截器,这是Ninject Interception扩展默认工作的方式.

这是一个条件拦截的例子:

class CustomInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if (invocation.Request.Method.Name == "MethodToIntercept")
            Console.WriteLine("Intercepted!");
        invocation.Proceed();
    }
}

您可以将它直接绑定到单个类,如下所示:

public class MyModule : NinjectModule
{
    public override void Load()
    {
        Bind<IFoo>().To<MyFoo>().Intercept().With<CustomInterceptor>();
    }
}

如果你想动态拦截单个类,那就是你要做的全部事情.

内核扩展看起来很有前途,因为它们允许您直接在声明中写入条件:

kernel.Intercept(ctx => ctx.Request.Service == typeof(IFoo))
    .With<CustomInterceptor>();

但是,如果您尝试根据正在执行的方法做出决策,这不是特别有用,因为这只会让您访问绑定上下文,而不是调用.主要是,此扩展存在,以便您可以选择在运行时拦截哪些类或服务(而不是方法).

最好坚持使用绑定语法,并将run-or-not-run逻辑直接写入拦截器,如第一个示例所示.

需要注意的一件重要事情是动态拦截器实际上会在它所绑定的任何类上为每个(公共/虚拟)方法运行,这可能效率非常低.不幸的是,Ninject Interception扩展必须采用最小公分母方法,因为它旨在支持多个代理库.如果您直接使用Castle,则可以使用use proxy generation hooks and interceptor selectors for fine-grained control,这实际上是推荐的方法.据我所知,从Ninject-DP2源代码可以看出,Ninject扩展不支持此功能.

就个人而言,由于这个原因,我从未在Ninject Interception扩展中获得很多成功,并且倾向于直接使用Castle DP2.但是,如果您正在小规模地执行此操作并且没有编写对性能敏感的应用程序,那么编写动态拦截器应该很好.

标签:c,net,aop,ninject,ninject-interception
来源: https://codeday.me/bug/20190518/1127457.html