Лучшая практика обертки регистратора

Я хочу использовать nlogger в своем приложении, возможно, в будущем мне нужно будет изменить систему ведения журнала. Поэтому я хочу использовать фасад лесозаготовки.

Знаете ли вы какие-либо рекомендации по существующим примерам, как их написать? Или просто дайте мне ссылку на некоторые лучшие практики в этой области.

    Раньше я использовал логические фасады, такие как Common.Logging (даже для того, чтобы скрыть свою собственную библиотеку CuttingEdge.Logging ), но в настоящее время я использую шаблон Injection Dependency, и это позволяет мне скрыть регистраторы за моей собственной (простой) абстракцией, которая придерживается обеих зависимостей Принцип инверсии и принцип разделяемости интерфейса (ISP), поскольку он имеет один член и потому что интерфейс определен моим приложением; а не внешняя библиотека. Минимизируя знание о том, что основные части вашего приложения имеют о существовании внешних библиотек, тем лучше; даже если у вас нет намерения когда-либо заменять вашу регистрационную библиотеку. Жесткая зависимость от внешней библиотеки усложняет проверку кода и усложняет ваше приложение API, который никогда не был разработан специально для вашего приложения.

    Это то, что абстракция часто выглядит в моих приложениях:

    public interface ILogger { void Log(LogEntry entry); } public enum LoggingEventType { Debug, Information, Warning, Error, Fatal }; // Immutable DTO that contains the log information. public class LogEntry { public readonly LoggingEventType Severity; public readonly string Message; public readonly Exception Exception; public LogEntry(LoggingEventType severity, string message, Exception exception = null) { if (message == null) throw new ArgumentNullException("message"); if (message == string.Empty) throw new ArgumentException("empty", "message"); this.Severity = severity; this.Message = message; this.Exception = exception; } } 

    Необязательно, эту абстракцию можно расширить с помощью некоторых простых методов расширения (позволяя интерфейсу оставаться узким и придерживаться ISP). Это делает код для пользователей этого интерфейса намного проще:

     public static class LoggerExtensions { public static void Log(this ILogger logger, string message) { logger.Log(new LogEntry(LoggingEventType.Information, message)); } public static void Log(this ILogger logger, Exception exception) { logger.Log(new LogEntry(LoggingEventType.Error, exception.Message, exception)); } // More methods here. } 

    Поскольку интерфейс содержит только один метод, вы можете легко создать реализацию ILogger которая ILogger до log4net , Serilog , Microsoft.Extensions.Logging , NLog или любую другую библиотеку ведения журнала и сконфигурируйте ваш контейнер DI, чтобы ввести его в classы с ILogger в их конструкторе.

    Обратите внимание, что наличие статических методов расширения поверх интерфейса с помощью одного метода сильно отличается от интерфейса со многими членами. Методы расширения – это просто вспомогательные методы, которые создают сообщение LogEntry и передают его через единственный метод на интерфейсе ILogger . Методы расширения становятся частью кода потребителя; а не частью абстракции. Мало того, что это позволяет развивать методы расширения без необходимости изменения абстракции, методы расширения и конструктор LogEntry всегда выполняются, когда используется абстракция журнала, даже когда этот регистратор заштрихован / издевается. Это дает больше уверенности в правильности запросов к журналу при запуске в тестовом наборе. Одночленный интерфейс упрощает тестирование; Наличие абстракции со многими участниками затрудняет создание реализаций (таких как макеты, адаптеры и декораторы).

    Когда вы это делаете, вряд ли когда-либо понадобится какая-то статическая абстракция, которую могут предложить логические фасады (или любая другая библиотека).

    Я использовал небольшую оболочку интерфейса + адаптер от https://github.com/uhaciogullari/NLog.Interface, которая также доступна через NuGet :

     PM> Install-Package NLog.Interface 

    Обычно я предпочитаю создавать интерфейс вроде

     public interface ILogger { void LogInformation(string msg); void LogError(string error); } 

    и во время выполнения я добавляю конкретный class, который реализуется из этого интерфейса.

    Отличное решение этой проблемы возникло в виде проекта LibLog .

    LibLog – это аббревиатура журнала с встроенной поддержкой основных регистраторов, включая Serilog, NLog, Log4net и Enterprise logger. Он устанавливается через диспетчер пакетов NuGet в целевую библиотеку в качестве файла источника (.cs) вместо ссылки .dll. Этот подход позволяет включать абзац записи, не заставляя библиотеку принимать внешнюю зависимость. Он также позволяет автору библиотеки включать ведение журнала без принуждения приложения-потребителя к явному предоставлению регистратора в библиотеку. LibLog использует рефлексию для определения того, какой конкретный регистратор используется и подключается к нему без какого-либо явного кода проводки в проекте (-ях) библиотеки.

    Таким образом, LibLog – отличное решение для входа в библиотечные проекты. Просто укажите и настройте конкретный регистратор (Serilog для выигрыша) в своем основном приложении или службе и добавьте LibLog в свои библиотеки!

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

    Оба include адаптеры для NLog и Log4net.

    С 2015 года вы также можете использовать .NET Core Logging, если вы создаете основные приложения .NET.

    Пакет для NLog для подключения:

    • NLog.Web.AspNetCore для основных пользователей ASP.NET
    • NLog.Extensions.Logging для пользователей .NET Core, например консольных проектов
    Interesting Posts

    попробуйте, попробуйте! & пытаться? какая разница, и когда использовать их?

    Выключить автозапуск для EditText?

    Преимущества / Недостатки разделения диска

    Mac OSX Terminal cmd / script для отображения секторов HDD в ожидании выделения

    java.io.NotSerializableException

    Как обнулить последовательность целых чисел в bash, чтобы все имели одинаковую ширину?

    Есть ли программное обеспечение для определения того, какое оборудование у меня есть, чтобы я мог найти драйверы для него?

    Отключить наследование web.config?

    Как избежать тупика mysql, обнаруженного при попытке получить блокировку; попробуйте перезапустить транзакцию “

    Это хорошая идея для указателей typedef?

    Возможно ли «заполнить» форму Google, используя данные из электронной таблицы google?

    Почему файл cmake GLOB-зло?

    $ {1: + “$ @”} в / bin / sh

    В чем разница между привязкой лямбды и метода на уровне выполнения?

    WIndows 7 64-разрядная версия 3,00 гб полезной памяти с установленным 4,00 гб

    Давайте будем гением компьютера.