Ведение журнала параметров и возврат коллекций с использованием PostSharp

#c# #.net #asp.net-web-api #log4net #postsharp

#c# #.net #asp.net-web-api #log4net #postsharp

Вопрос:

Я хотел бы использовать аспект Log PostSharp, чтобы легко регистрировать все значения входа и выхода моих конечных точек async Web API.

Например:

 [Log]
[HttpGet]
public async Task<List<string>> Get(List<int> ids)
{
    var result = await GetResult(ids);
    return resu<
}
  

Результат:

 DEBUG Controllers.MyController - Entering: MyController.Get(this = {Controllers.MyController}) : 
                                         {System.Collections.Generic.List`1[System.String]}

DEBUG Controllers.MyController - Leaving: MyController.Get(this = {Controllers.MyController}) : 
         {System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[System.String]]}
  

Вместо фактических значений. Как я мог этого добиться?

Ответ №1:

Аспект журнала не поддерживает асинхронные методы в PostSharp 4.3 и более старых версиях. Вы можете легко разработать свой собственный пользовательский аспект ведения журнала:

 [PSerializable]
public sealed class CustomLog : OnMethodBoundaryAspect
{
    public CustomLog()
    {
        ApplyToStateMachine = true;
    }

    public override void OnSuccess(MethodExecutionArgs args)
    {
        var stringBuilder = new StringBuilder();
        var declaringType = args.Method.DeclaringType;

        stringBuilder.Append("Exiting ");
        stringBuilder.Append(declaringType.FullName);
        stringBuilder.Append('.');
        stringBuilder.Append(args.Method.Name);

        if (!args.Method.IsConstructor amp;amp; ((MethodInfo) args.Method).ReturnType != typeof(void))
        {
            stringBuilder.Append(" with return value ");
            stringBuilder.Append(args.ReturnValue);
        }

        Logger.WriteLine(stringBuilder.ToString());
    }
}
  

Важно то, что в конструкторе: ApplyToStateMachine = true указывает PostSharp правильно применять аспект к конечным машинам (асинхронным методам и перечислителям). Без ApplyToStateMachine = true этого CustomLog будет вести себя так же, как и стандартный аспект журнала.

Этот пример не работает с универсальными методами и типами, плохо работает с более сложными типами аргументов и возвращаемых значений и имеет много других ограничений. Вы можете найти более полное решение в этом примере PostSharp: CustomLogging . К сожалению, пример не содержит никакой информации о ApplyToStateMachine = true .

РЕДАКТИРОВАТЬ 04.11.2016: этот пример работает в PostSharp 5.0.10 даже для асинхронных методов. args.ReturnValue содержит возвращаемое значение асинхронного метода.

Комментарии:

1. args.ReturnValue равно нулю. Есть идеи, почему?

2. Это похоже на ошибку или странное ограничение onmethod boundaryaspect. Я добавил пример, как его обойти, но он далек от идеала.

3. Было бы неплохо узнать, что не работает :). Но, похоже, ограничение было исправлено, и первый пример, похоже, работает в PostSharp 5.0.10.

4. Извините 🙂 Я имел в виду, что «Не работает» args.ReturnValue всегда равно нулю. Похоже, мне, возможно, придется подождать PS 5.