Autofac接口拦截器嵌套方法调用未触发,如何解决?
解决Autofac拦截器全链路拦截失效的问题
你遇到的这个问题其实很常见——当类内部方法互相调用时,默认不会触发拦截器,核心原因是内部调用没有经过代理对象。
Autofac的EnableInterfaceInterceptors是给接口生成代理类:你从容器拿到的IWorker其实是代理实例,当你调用代理的方法时,拦截器才会工作。但在A类的Method1里直接写Method2(),本质是this.Method2(),这是直接调用真实A实例的方法,完全绕开了代理层,自然不会触发Method2的拦截。
下面给你两种可行的解决方案:
方案1:通过依赖注入自身(接口拦截模式适用)
修改A类,让它通过构造函数注入IWorker实例,然后在Method1里用这个注入的实例调用Method2,这样就会走代理触发拦截:
class A : IWorker { private readonly IWorker _selfProxy; // 注入自身的代理实例 public A(IWorker selfProxy) { _selfProxy = selfProxy; } public int Method1() { // 调用代理实例的Method2,而非直接调用this.Method2 return 2 * _selfProxy.Method2(); } public int Method2() { return 5; } }
注册代码不需要大改,Autofac会自动把IWorker的代理实例注入到A的构造函数中:
var builder = new ContainerBuilder(); builder.RegisterType<WorkerUsageLogger>(); builder.RegisterType<A>().As<IWorker>().EnableInterfaceInterceptors().InterceptedBy(typeof(WorkerUsageLogger)); var container = builder.Build(); IWorker worker = container.Resolve<IWorker>();
方案2:使用类拦截(虚拟方法模式)
如果不想修改类的依赖结构,可以改用Autofac的类拦截功能,只需要把要拦截的方法标记为virtual:
修改A类的方法为虚拟:
class A : IWorker { public virtual int Method1() { return 2 * Method2(); } public virtual int Method2() { return 5; } }
注册时改用EnableClassInterceptors:
var builder = new ContainerBuilder(); builder.RegisterType<WorkerUsageLogger>(); builder.RegisterType<A>().As<IWorker>().EnableClassInterceptors().InterceptedBy(typeof(WorkerUsageLogger)); var container = builder.Build(); IWorker worker = container.Resolve<IWorker>();
类拦截是生成A的子类代理,当Method1里调用Method2()时,实际调用的是代理子类的重写方法,所以会触发拦截器。
验证效果
两种方案调用worker.Method1()后,都会得到你预期的输出:
Calling method Method1 Calling method Method2 Completed method Method2 Completed method Method1
内容的提问来源于stack exchange,提问作者Gaweł Szymański
相关产品推荐
相关产品推荐

