嵌套呼叫不会触发拦截器

时间:2018-05-14 14:10:36

标签: c# .net autofac aop interceptor

我想将拦截器附加到一些方法,其中一个方法可能会调用其他截获的方法,只运行第一个拦截器。我怎样才能让它发挥作用:

class A : IWorker
{
    int Method1()
    {
        return 2*Method2();
    }

    int Method2()
    {
        return 5;
    }
}

拦截器实施

public class WorkerUsageLogger : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var indent = new string('\t', tabs);
        Console.WriteLine($"{indent}Calling method {invocation.Method.Name}.");
        tabs++;
        invocation.Proceed();
        tabs--;
        Console.WriteLine($"{indent}Completed method {invocation.Method.Name}");
    }
}

附加拦截器

var builder = new ContainerBuilder();
builder.RegisterInstance(new WorkerUsageLogger());
builder.RegisterType<A>().As<IWorker>().EnableInterfaceInterceptors().InterceptedBy(typeof(WorkerUsageLogger));
var container = builder.Build();
IWorker worker = container.Resolve<IWorker>();

致电

worker.Method1();

我期待:

"Calling method Method1"
    "Calling method Method2"
    "Completed method Method2"
"Completed method Method1"

我正在

"Calling method Method1"
"Completed method Method1"

1 个答案:

答案 0 :(得分:0)

拦截器返回类型为IWorker的对象,该对象具有通过拦截器执行日志记录的代码。实际上没有任何内容编辑类A中的代码来拦截,执行日志记录等。因为所述代码调用同一A类中的方法,即this,所以你注入的拦截器在这些嵌套调用期间,永远不会触及IWorker调用。

要观察此情况,请尝试打印worker.GetType()(或观察调试器中的类型),并注意属于A类型。

这可以是单一责任原则的一个示例,因为您的接口实现不应该调用this对象上的内容,因为它可以分解日志记录和单元测试。如果您无法将解决方案消化为单独的接口,则可以考虑将实现请求设置为具有相同接口类型的属性,并调用