Лучший способ получить имена и значения параметров метода в словаре - PullRequest
0 голосов
/ 30 января 2020

В настоящее время я добавляю некоторые записи в наше приложение, чтобы помочь отладке в будущем. Чтобы достичь этого, я написал DLL с классом stati c, который в основном действует как слой между нашим приложением и записывает в выбранный источник журнала, это обычно - понимание приложения.

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

var methodName = MethodBase.GetCurrentMethod().Name;    
var methodParameters = new Dictionary<string, string> { { "Parameter1", "Parameter1 Value" }, { "Parameter2", "Parameter2 Value" } };
appInsightsClient.TrackTrace(methodName, methodParameters);

, и это прекрасно работает.

Мне интересно, есть ли лучший / более чистый способ добиться этого? Для методов с большим количеством параметров это легко станет трудно читать. Я знаю, что MethodBase.GetCurrentMethod () имеет метод для GetParameters (), но они не возвращают значение. Это также зависит от того, что разработчик установил переменные methodParameters / methodName обратно в ноль, чтобы они собирались сборщиком мусора, и при большом количестве удаляемых методов я не хочу использовать слишком много памяти.

I Я понимаю, что этот вопрос отчасти субъективен и мнение отдельного разработчика, но я не могу найти какие-либо альтернативы или примеры, и не могу быть единственным человеком, который делает это.

1 Ответ

0 голосов
/ 30 января 2020

Одним из способов решения этой проблемы является использование AOP framework. Я знаю по крайней мере пару из них. Одним из них является PostSharp , который действительно многофункциональный, но не бесплатный. Другой, с которым я сталкивался, это MrAdvice .

В основном, что вы можете сделать с этой структурой, это создать точки перехвата методов. Вы можете применять пользовательские логи c при входе и выходе из метода. Что вы можете сделать, это проверить информацию о методе и использовать его в журнале. Вы можете украсить интересующие вас методы, чтобы иметь возможность контролировать, какие методы регистрируются или не регистрируются.

Например, используя MrAdvice, вы можете сделать что-то вроде:

public sealed class AppInsightsRequestAttribute : Attribute, IMethodAsyncAdvice
    {
        private static readonly TelemetryClient TelemetryClient = new TelemetryClient(TelemetryConfiguration.Active);

        public async Task Advise(MethodAsyncAdviceContext context)
        {
            var parameters = context.TargetMethod.GetParameters();
            var parameterDescription = string.Join(", ",
                parameters.Select(p => $"{p.ParameterType.Name} {p.Name}"));
            var signature = $"{context.Target ?? context.TargetType}.{context.TargetName}({parameterDescription})";

            using (var operation = TelemetryClient.StartOperation<RequestTelemetry>(signature))
            {
                try
                {
                    await context.ProceedAsync();
                }
                catch (Exception)
                {
                    operation.Telemetry.Success = false;
                    throw;
                }
                finally
                {
                    EnrichRequestTelemetry(operation.Telemetry, context, parameters);
               }
            }
        }

        private static void EnrichRequestTelemetry(ISupportProperties telemetry, MethodAsyncAdviceContext context, IReadOnlyList<ParameterInfo> parameters)
        {
            telemetry.Properties.Add(
                new KeyValuePair<string, string>("Accessibility", 
                    context.TargetMethod.Attributes.ToVisibilityScope().ToString()));

            for (var i = 0; i < context.Arguments.Count; i++)
            {
                telemetry.Properties.Add($"ARG {parameters[i].Name}", context.Arguments[i].ToString());
            }
        }
    }

Этот код создаст элемент RequestTelemetry и отправит его на рассмотрение приложения. Метод EnrichRequestTelemetry добавит аргументы и значения метода в качестве пользовательских свойств к элементу.

Затем вы можете украсить свои методы следующим образом: (есть больше опций, но это демонстрирует возможность)

public class SomeClass
    {
        [AppInsightsRequest]
        public async Task<string> SayHello(string to)
        {
            var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
            string response = null;

            try
            {
                var greeting = $"Hello {to}";
                telemetryClient.TrackTrace($"Sending {greeting}");

                response = await SomeService.SendAsync(greeting);
            }
            catch (Exception exception)
            {
                telemetryClient.TrackException(exception);
            }

            return response;
        }
    }

Полный пример использования консольного приложения для отправки телеметрии для понимания приложений можно найти в этом репозитории , который я создал.

...