Ninject 拦截具有特定属性的任何方法?

标签 ninject aop ninject-interception

我怎样才能让 Ninject.Extensions.Interception 基本上让我将特定的拦截器绑定(bind)到任何具有属性的方法......psudocode:

Kernel.Intercept(context => context.Binding.HasAttribute<TransactionAttribute>())
      .With<TransactionInterceptor>

像这样的类(class):
public SomeClass
{
    [TransactionAttribute]
    public void SomeTransactedMethod()
    { /*do stuff */ }
}

最佳答案

假设您使用 Ninject.Extensions.Interception这应该可以解决问题

public class TransactionInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        // Do something...
    }
}

public class TransactionAttribute : InterceptAttribute
{
    public override IInterceptor CreateInterceptor(IProxyRequest request)
    {
        return new TransactionInterceptor();
    }
}

public class SomeClass
{
    [Transaction]
    public virtual void SomeTransactedMethod() { }
}

确保应该被拦截的方法被标记为虚拟的。

SomeTransactedMethod()被称为应该被拦截。
var kernel = new StandardKernel();
kernel.Bind<SomeClass>().ToSelf();

var someClass = kernel.Get<SomeClass>();
someClass.SomeTransactedMethod();

更新

您可以创建自定义计划策略。
public class CustomPlanningStrategy<TAttribute, TInterceptor> :
    NinjectComponent, IPlanningStrategy
        where TAttribute : Attribute
        where TInterceptor : IInterceptor
{
    private readonly IAdviceFactory adviceFactory;
    private readonly IAdviceRegistry adviceRegistry;

    public CustomPlanningStrategy(
        IAdviceFactory adviceFactory, IAdviceRegistry adviceRegistry)
        {
            this.adviceFactory = adviceFactory;
            this.adviceRegistry = adviceRegistry;
        }

        public void Execute(IPlan plan)
        {
            var methods = GetCandidateMethods(plan.Type);
            foreach (var method in methods)
            {
                var attributes = method.GetCustomAttributes(
                    typeof(TAttribute), true) as TAttribute[];
                if (attributes.Length == 0)
                {
                    continue;
                }

                var advice = adviceFactory.Create(method);

                advice.Callback = request => request.Kernel.Get<TInterceptor>();
                adviceRegistry.Register(advice);

                if (!plan.Has<ProxyDirective>())
                {
                    plan.Add(new ProxyDirective());
                }
            }
        }
    }

    private static IEnumerable<MethodInfo> GetCandidateMethods(Type type)
    {
        var methods = type.GetMethods(
            BindingFlags.Public | 
            BindingFlags.NonPublic | 
            BindingFlags.Instance
        );

        return methods.Where(ShouldIntercept);
    }

    private static bool ShouldIntercept(MethodInfo methodInfo)
    {
        return methodInfo.DeclaringType != typeof(object) &&
               !methodInfo.IsPrivate &&
               !methodInfo.IsFinal;
    }
}

现在应该可以了。
var kernel = new StandardKernel();
kernel.Components.Add<IPlanningStrategy, 
    CustomPlanningStrategy<TransactionAttribute, TransactionInterceptor>>();

kernel.Bind<SomeClass>().ToSelf();

var someClass = kernel.Get<SomeClass>();
someClass.SomeTransactedMethod();

关于Ninject 拦截具有特定属性的任何方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6386461/

相关文章:

c# - Ninject拦截动态代理问题

c# - 存储库上的 Ninject WCF 垃圾收集

c# - 何时使用单例、 transient 和使用 Ninject 和 MongoDB 的请求

c# - Dotnet 核心中的 AOP : Dynamic Proxy with Real Proxy in Dotnet core

java - 推断aspectj方法中参数的类型

忍者拦截器

wcf - 尝试为 WCF 安装 nInject 时找不到 NinjectWcfApplication 引用

reflection - Ninject 注入(inject)到通过反射构造的对象中

java - Maven 的 AspectJ 模块依赖 - 如何使用依赖模块的类型间声明方法

c# - Ninject 方法级拦截带参数