Это интересный подход, однако он, кажется, страдает от недостатка, что все введенные в систему регистраторы (или один инжектор) будут одним и тем же экземпляром (или будут иметь одно и то же имя, имя класса NLogLoggingService.Это означает, что вы не можете очень легко контролировать гранулярность ведения журнала (т. е. включить ведение журнала на уровень «Информация» в одном классе и «Предупреждать» в другом классе). Также, если вы решите использовать сайт вызова форматирования маркеров, вы всегда получите сайт вызова вызова в NLog регистратора, а не на месте вызова в коде приложения
Вот сокращенный вариант регистратора, который был связан:.
[Export(Services.Logging.LoggingService, typeof(ILoggingService))]
class NLogLoggingService : ILoggingService
{
Logger log; public NLogLoggingService()
{
log = LogManager.GetCurrentClassLogger();
}
public void Debug(object message)
{
log.Debug(message);
}
public void DebugWithFormat(string format, params object[] args)
{
if (args.Length == 0)
{
log.Debug(format);
}
else
{
Debug(string.Format(format, args));
}
}
public bool IsDebugEnabled
{
get
{
return log.IsDebugEnabled;
}
}
}
В конструкторе LogManager.GetCurrentClassLogger()
используется для получения регистратора NLog. GetCurrentClassLogger вернет логгер NLog, который «назван» на основе «текущего» типа, который в этом случае является NLogLoggingService. Итак, чтобы настроить NLog в файле app.config, вы будете конфигурировать на основе того, что регистратор называется «SoapBox.Core.NLogLoggingService». Обычно, в коде, который использует NLog (или log4net) непосредственно, каждый класс получает свой собственный уникальное имя логгера, как это:
namespace MyNamespace
{
public class MyClass1
{
private static readonly Logger logger LogManager.GetCurrentClassLogger();
public void DoSomeWork()
{
logger.Info("Logging from inside MyClass1.DoSomeWork");
}
}
public class MyClass2
{
private static readonly Logger logger LogManager.GetCurrentClassLogger();
public void DoSomeWork()
{
logger.Info("Logging from inside MyClass2.DoSomeWork");
}
}
}
Теперь протоколирование для MyClass1 и MyClass2 индивидуально контролируемое. Вы можете настроить разные уровни для каждого класса, отправить их другим целям или полностью отключить один или оба. В качестве альтернативы, из-за концепции иерархии журналов как в log4net, так и в NLog, вы можете управлять журналом в обоих классах одновременно, настраивая «регистратор» для пространства имен (в данном случае это MyNamespace) или любое пространство имен «предков». Если для полнофункционального имени нет логина, то структура ведения журнала существенно перемещает иерархию, рассматривая имя строки с разделителями точек и удаляя последний кусок и проверяя, настроен ли этот журнал. Итак, в этом случае мы запрашиваем регистраторы для MyNamespace.MyClass1 и MyNamespace.MyClass2.Я могу настроить файл app.config, чтобы иметь журнал MyNamespace в «info» и записывать в целевой файл (appender в log4net-talk). Если бы я это сделал, то оба регистратора, которые я запросил через их полностью квалифицированные имена, наследуют конфигурацию MyNamespace.
С предлагаемым способом ввода NLog через MEF у вас будет только один экземпляр регистратора, поэтому вы не сможете настроить каждый класс для записи по-разному. Кроме того, как я уже упоминал ранее, если вы выберете регистрацию информации сайта звонка, вы всегда получите «SoapBox.Core.NLogLoggingService» для класса и «Debug» (или DebugWithFormat, или Info, или InfoWithFormat и т. Д.) Для этого метода.
Это, похоже, проблема с успешным вводом регистраторов из log4net и NLog. Вы можете увидеть question, что я спросил об этом выпуске пару месяцев назад.
В конечном итоге мне удалось выяснить, как некоторые среды инъекций зависимостей могут успешно вводить log4net и логические записи NLog, которые являются специфическими для создаваемого класса (т.е. если среда DI создает экземпляр MyClass, что, в свою очередь, зависит от интерфейса ILogger, то MyClass получит регистратор, который по сути эквивалентен тому, что произошло бы, если MyClass запросил сам журнал регистрации через LogManager.GetCurrentClassLogger api). Обычно «резольверы» в каркасах DI/IoC получают текущий контекст (содержащий, помимо прочего, тип создаваемого объекта). Имея доступ к этому типу, становится проще, чтобы речевой механизм, зависящий от структуры ведения журнала, получил этот тип и передал его вместе с фреймворком ведения журнала для создания регистратора, соответствующего этому типу.
Чтобы получить максимальную отдачу от возможностей NLog (и log4net), вам действительно хотелось бы сказать MEF, что ваш класс зависит от «ILogger», а также что экземпляр «ILogger», который вводится в ваш класс должен зависеть от типа вашего класса.
Я не знаю, как легко достичь этого с помощью MEF. Кроме того, вы можете обернуть статический LogManager NLog в ILogManager и ввести его. Это отклонилось бы от обычной парадигмы «инъекции ILogger».
Подводя итог: Если вы вводите NLog через MEF таким образом, вы действительно сможете зарегистрироваться в NLog, но у вас будет только один именованный логгер (SoapBox.Core.NLogLoggingService). Это означает, что вы не сможете контролировать с какой-либо степенью детализации - либо для уровней/включения/выключения, либо для вывода (NLog Target/log4net Appender)
У меня нет хорошего ответа, что делать дальше как ввод NLog через MEF и сохранение гранулярности/гибкости, которую дает вам «сырой» NLog.
Я могу сказать, что мы решили использовать Common.Logging for .NET для абстрагирования рамки ведения журнала, но мы решили НЕ вводить каротаж. Вместо этого мы просто будем использовать статический LogManager (как это предусмотрено Common.Logging) для раздачи журналов.
Это прекрасная реализация MEF-совместимого регистратора NLog, но он страдает от нескольких недостатков: 1. Все регистраторы MEF-ed для приложения фактически будут одним и тем же журналом, поэтому у вас нет большой контроль над вашим протоколированием. 2. Информация о вызывающем сайте теряется, поскольку будет использоваться сайт вызова класса ведения журнала. У меня на голове нет лучшего предложения для MEF, но я думаю, что стоит отметить эти недостатки. См. Мой ответ для более длинной версии. – wageoghe