Вложенный вызов не вызывает перехватчиков - PullRequest
0 голосов
/ 14 мая 2018

Я хочу прикрепить перехватчик к нескольким методам, из которых один из них может вызывать другие перехваченные методы, только первый перехватчик запускается. Как я могу заставить это работать:

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 голосов
/ 15 мая 2018

Перехватчик возвращает объект типа IWorker, у которого есть код для прохождения через ваш перехватчик, который выполняет регистрацию.На самом деле ничто не редактирует код в классе A для перехвата, ведения журнала и т. Д. Поскольку указанный код вызывает методы в том же классе A, то есть this, перехватчик, введенный вами в вызов IWorker, никогда не будеткоснулся во время этих вложенных вызовов.

Чтобы наблюдать это, попробуйте напечатать worker.GetType() (или наблюдать тип в отладчике) и обратите внимание, что он не будет иметь тип A.

Это может быть примером принципа единой ответственности, в котором реализации вашего интерфейса не должны вызывать вещи для объекта this, потому что это может привести к поломке регистрации и модульному тестированию.Если вы не можете переварить свое решение в отдельные интерфейсы, вы можете рассмотреть вопрос о том, чтобы сделать запрос на реализацию свойством интерфейса того же типа и вызвать , что .

...