Dependency injection 使用Autofac的方法级属性拦截

Dependency injection 使用Autofac的方法级属性拦截,dependency-injection,autofac,ioc-container,Dependency Injection,Autofac,Ioc Container,(这是一个与SimpleInjector相关的问题。建议我为每个IoC容器创建单独的问题。) 使用Unity,我可以像这样快速添加基于属性的拦截 public sealed class MyCacheAttribute : HandlerAttribute, ICallHandler { public override ICallHandler CreateHandler(IUnityContainer container) { return this; }

(这是一个与SimpleInjector相关的问题。建议我为每个IoC容器创建单独的问题。)

使用Unity,我可以像这样快速添加基于属性的拦截

public sealed class MyCacheAttribute : HandlerAttribute, ICallHandler
{
   public override ICallHandler CreateHandler(IUnityContainer container)
   {
        return this;
   }

   public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
   {
      // grab from cache if I have it, otherwise call the intended method call..
   }
}
然后我以这种方式向Unity注册:

  container.RegisterType<IPlanRepository, PlanRepository>(new ContainerControlledLifetimeManager(),
           new Interceptor<VirtualMethodInterceptor>(),
           new InterceptionBehavior<PolicyInjectionBehavior>());

我正在探索类似的方法在Autofac中实现这一点。从我阅读和搜索的内容来看,似乎只有接口/类型级别的截取可用。但是我喜欢使用这种类型的属性控制的拦截行为来装饰单个方法的选项。有什么建议吗?

你说的没有方法级拦截是对的。 但是,当您使用write类型拦截器时,您可以访问正在调用的方法。注意:这取决于Autofac.Extras.DynamicProxy 2软件包

    public sealed class MyCacheAttribute : IInterceptor
    {

        public void Intercept(IInvocation invocation)
        {
            // grab from cache if I have it, otherwise call the intended method call..

            Console.WriteLine("Calling " + invocation.Method.Name);

            invocation.Proceed();
        }
    }
注册应该是这样的

     containerBuilder.RegisterType<PlanRepository>().As<IPlanRepository>().EnableInterfaceInterceptors();
     containerbuilder.RegisterType<MyCacheAttribute>();
containerBuilder.RegisterType().As().EnableInterfaceInterceptors();
containerbuilder.RegisterType();

看起来Autofac和SimpleInjector都在使用动态代理,对属性拦截没有现成的支持。Steven在这里提供了接口拦截的典型解决方案:@Calvin:更准确地说:简单的注入器甚至不支持拦截。没有用于执行拦截的包或扩展。
     containerBuilder.RegisterType<PlanRepository>().As<IPlanRepository>().EnableInterfaceInterceptors();
     containerbuilder.RegisterType<MyCacheAttribute>();