2016-10-05 15 views
0

Я начинаю новый проект и думаю об использовании перехвата SimpleInjector (https://simpleinjector.readthedocs.io/en/latest/InterceptionExtensions.html) для отслеживания параметров ввода/вывода и регистрации параметров и возвращаемых значений и т. Д. Я использовал этот перехватчик в прошлом, и он прекрасно работает. Но мои предыдущие проекты не были асинхронными/ждут. Этот новый проект имеет множество методов, которые все async/ждут, и мне было интересноПерехват SimpleInjector в коде async/await

  • будет ли этот перехватчик работать для методов async/wait?
  • Какие изменения необходимы в этом перехватчике, чтобы заставить его работать для методов async/wait?

Я понимаю, что декораторы намного лучше, чем перехват, но написание декоратора для каждого интерфейса, который я хочу отслеживать, не является тем, что я с нетерпением жду.

UPDATE: Я пробовал этот перехватчик в моем асинхронном/ожидающем коде, и он вводит мой код отслеживания. Тем не менее, я получал странные результаты в некоторых частях моего приложения. У меня не было возможности углубиться в то, почему отключение перехвата заставило бы его работать нормально и почему, когда перехват был включен, он не будет работать так, как ожидалось. Это может быть очень плохо с моим кодом.

Я надеялся, что если кто-то, кто уже использовал это расширение перехвата в своем коде, сможет указать мне в правильном направлении.

+1

'будет перехватчик работать на асинхронном/ждут методы' ли это работать, когда вы пробовали? –

+1

«Это сработает?» Если вы явно пишете свой метод для работы с асинхронными вызовами, да. – Steven

ответ

1

будет ли этот перехватчик работать для методов async/await?

Асинхронный код на C# является синтаксическим сахаром сверху Task. Это означает, что если ваш код должен сделать что-нибудь полезное после того, как вызовет метод async, вы получите вызов ContinueWith по возвращенному Task (или используйте синтаксис C#). Если вы принимаете асинхронный подход в своем перехватчике, вы не сможете выполнять логику после обернутого объекта.

Для того, чтобы выполнить эту работу, вам нужно будет явно проверить, возвращает ли завернутый метод Task, и если это так, вы должны сделать асинхронные операции, переведя код «после» с помощью ContinueWith.

Это одна из многих причин, по которой я считаю, что перехват уступает использованию декораторов. Декораторы позволяют вашему коду быть намного чище, не использовать рефлексию, давать полную поддержку времени компиляции, повышать производительность, не зависеть от библиотеки перехвата, а также заставлять вас использовать гораздо более ТВОРЧЕСКИЙ дизайн приложения.

Тем не менее, документация MonitoringInterceptor-х будет выглядеть следующим образом, когда он принимает во внимание асинхронность:

class MonitoringInterceptor : IInterceptor 
{ 
    private readonly ILogger logger; 

    public MonitoringInterceptor(ILogger logger) { 
     this.logger = logger; 
    } 

    public void Intercept(IInvocation invocation) { 
     var watch = Stopwatch.StartNew(); 

     // Calls the decorated instance. 
     invocation.Proceed(); 

     var task = invocation.ReturnValue as Task; 

     if (task != null) { 
      invocation.ReturnValue = LogElapsedAsync(task, invocation, watch); 
     } else { 
      LogElapsed(invocation, watch); 
     } 
    } 

    private async Task LogElapsedAsync(Task task, IInvocation i, Stopwatch w) { 
     await task; 
     LogElapsed(i, w); 
    } 

    private void LogElapsed(IInvocation invocation, Stopwatch watch) { 
     var decoratedType = invocation.InvocationTarget.GetType(); 

     this.logger.Log(string.Format("{0} executed in {1} ms.", 
      decoratedType.Name, watch.ElapsedMilliseconds)); 
    } 
} 
+0

В примере расширения перехвата метод 'IInterceptor.Intercept' возвращает' void'. Если я хочу использовать его с 'async/await', мне придется изменить возвращаемый тип на' Task' и внести соответствующие изменения? Или, если я возьму код из [Асинхронное программирование: перехват асинхронных методов с использованием перехвата Unity] (https://msdn.microsoft.com/en-us/magazine/dn574805.aspx) и заверните 'invocation.ReturnValue', если' invocation .GetConcreateMethod(). ReturnType' '' Task'? – user2321864

+1

@ user2321864: См. Обновление. – Steven

 Смежные вопросы

  • Нет связанных вопросов^_^