如何使用 Ninject 设置可选方法拦截? [英] How to set up an optional method interception with Ninject?

查看:26
本文介绍了如何使用 Ninject 设置可选方法拦截?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose I have a class in which I want to sometimes* (but now always) intercept some (but not all) methods. The way I understand it, this can be done either with, say, InterceptAround() in my Ninject module (in the higher-level code), or with an InterceptAttribute-derived attribute on those methods (at the implementation level).

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

I don't really like the first way of doing it, because it requires the consumer to know the details, there'll be many classes with many methods. But I don't like the second way either, since I don't see how to disable (or, rather, not to enable) the interception, as the attribute is fused with the code.

是否有一些已知的方法可以解决这个问题?

Is there some known approach to solve this problem?

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

*: for the lifetime of the application.

推荐答案

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

It sounds as though you are referring to an ordinary dynamic interceptor, which is how the Ninject Interception extension works by default.

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

Here's an example of a conditional interception:

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

您可以像这样将它直接绑定到单个类:

You bind it directly to a single class like so:

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

如果你想动态拦截单个类,这几乎就是你所要做的.

And that's pretty much all you have to do if you want to dynamically intercept a single class.

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

The kernel extensions look promising because they let you write conditions directly into the declaration:

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

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

However, this isn't particularly useful if you're trying to make decisions based on the method being executed, because this only gives you access to the binding context, and not the invocation. Mainly, this extension exists so that you can choose which classes or services (as opposed to methods) to intercept at runtime.

最好坚持绑定语法,并将运行或不运行逻辑直接写入拦截器,如第一个示例所示.

Better to stick to the binding syntax, and write the run-or-don't-run logic directly into the interceptor, as illustrated in the first example.

需要注意的一件重要事情是,动态拦截器实际上会针对它绑定到的任何类上的每个(公共/虚拟)方法运行,这可能非常低效.不幸的是,Ninject Interception 扩展必须采用最低公分母方法,因为它旨在支持多个代理库.如果直接使用Castle,可以使用代理生成钩子和拦截器选择器进行细粒度控制,这实际上是推荐的方法.据我所知,Ninject-DP2 源代码不支持 Ninject 扩展.

One important thing to note is that a dynamic interceptor will actually run for every (public / virtual) method on whichever class it is bound to, which can be very inefficient. Unfortunately, the Ninject Interception extension has to take a lowest-common-denominator approach because it is designed to support multiple proxy libraries. If you use Castle directly, you can use proxy generation hooks and interceptor selectors for fine-grained control, which is actually the recommended approach. As far as I can tell from the Ninject-DP2 source code, this is not supported with the Ninject extension.

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

Personally, I've never had a lot of success with the Ninject Interception extension for exactly this reason, and tend to stick to using Castle DP2 directly. However, if you're doing this on a small scale and aren't writing a performance-sensitive app, you should be fine writing dynamic interceptors.

这篇关于如何使用 Ninject 设置可选方法拦截?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆