Во-первых, я хочу поговорить о проблеме, которая возникнет у вас при использовании атрибутного подхода. Предположим, у вас есть метод AddFirstFourNumbers
, украшенный атрибутом Log
, как описано в вашем вопросе.
Атрибут существует как метаданные в методе. Вот и все. Любые содержащиеся в нем методы будут вызываться только в том случае, если вы их специально вызываете. Другими словами:
var attrib = typeof(ClassWithAddFirstFourNumbers) // get the attribute
.GetMethod(nameof(AddFirstFourNumbers))
.GetAttributes<LogAttribute>()
.FirstOrDefault();
if (attrib != null) attrib.BeforeLog();
AddFirstFourNumbers(somenumbers);
if (attrib != null) attrib.AfterLog();
Теперь вы можете использовать свой лямбда-подход, чтобы создать метод, который получает этот атрибут, но вам потребуется go подход дерева выражений (см. Ниже), чтобы получить атрибут изнутри лямбда-зов. И теперь у вас есть атрибут без реальной причины. Не весело.
Я представляю это как альтернативу. Я полагаю, что вы, возможно, задумывались над этим.
Во-первых, ваш Log
метод, в том виде, в котором он реализован, не получит название метода, который вы передаете в лямбду. Вы можете изменить способ получения имени метода , используя выражения , но это будет означать, что ваши лямбда-вызовы не могут быть намного больше, чем один вызов метода, а не группы методов или доступ к свойствам.
Я думаю, вы злоупотребляете обработкой исключений. Я предлагаю вам ловить исключения на самом высоком уровне, где вы можете принять решение о том, как их обработать . Там у вас будет стек вызовов, который укажет, где произошло исключение. Как правило, нет необходимости регистрировать исключения там, где они произошли , если только вам не нужно регистрировать переменные, чтобы понять причину исключения. (KeyNotFoundException
не говорит вам , какой ключ не был найден!) Система ведения журнала общего назначения, как вы предлагаете в своем вопросе, не могла - не могла - захватить эти переменные .
Это более субъективное мнение, но я чувствую, что вы немного обдумываете это. Это моя рекомендация. Сохраняйте это простым и просто добавьте в свои методы некоторые записи:
public int AddFirstFourNumbers(params int[] numbahs)
{
int product;
product += numbahs[0];
product += numbahs[1];
Debug("Still adding numbers but we'll require additional pylons soon");
product += numbahs[2];
product += numbahs[3];
return product;
}
И:
var sum = AddSomeNumbers(somenumbers);
Debug($"{nameof(AddSomeNumbers)} on {somenumbers.Length} numbers -> {sum}");
Это обеспечивает большую гибкость и полезность в ваших сообщениях журнала, и не мешает вашему код гораздо больше, чем лямбда-подход. Это означает, что вам нужно написать сообщение журнала, но нет правила, чтобы все они были последовательными и содержали полные советы по отладке. Что-то простое, например Debug($"sum={sum}");
, все еще полезно и не требует много времени для ввода.
Хорошо. Эта последняя идея, вероятно, даст вам наибольшую выгоду от того, чего вы хотите достичь. У меня есть следующие условия, верно?
Вы хотите знать, откуда вы входите. Класс и метод. Даже номер строки.
Вы хотели бы знать поток или пользователя.
Вы хотели бы иметь возможность добавить дополнительную информацию о регистрации глобально без необходимости изменения вашего кода.
Вы хотели бы иметь возможность добавлять дополнительную информацию о регистрации в конкретизировать c классы или пространства имен , без необходимости изменения кода.
Используйте такие библиотеки, как NLog, log 4net, Serilog или другие. Они все очень хорошие. Все они позволят вам определить глобальный шаблон для ваших сообщений журнала: имя класса, имя метода, идентификатор потока, имя пользователя, метка времени, переменная среды и т. Д. c. Я больше всего знаком с NLog, который предоставляет их как рендеринг макетов . Я покажу вам, как это работает с помощью NLog.
public class YourExampleClass
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public void ExampleMethod()
{
try
{
Logger.Info("Hello world");
}
catch (Exception ex)
{
Logger.Error(ex, "Goodbye cruel world");
}
}
}
С этим кодом другая указанная мной информация, такая как местоположение и метка времени, добавляется в конфигурацию с использованием средств визуализации макета. Аккуратно, а? Это не потребует масштабных изменений в вашей программе. Вы можете войти в классы, из которых вы хотите войти, и другие классы не будут изменены.
Для вашего удобства, вот официальный учебник NLog .