ASP.NET 5 Лучшая практика для регистрации исключений в слоях

У меня есть проект с использованием ASP.NET 5 и MVC 6. У меня есть несколько слоев:

  • Мой уровень представления
  • Мой слой модели предметной области
  • Мой уровень инфраструктуры
  • Мой уровень бизнес-логики
  • И мои уровни доступа к данным.

На данный момент я регистрирую исключения в методах своих контроллеров, используя внедрение зависимостей.

private readonly ILogger<CustomerController> _logger;
public CustomerController(ILogger<CustomerController> logger)
{
     _logger = logger;
}

public bool TestLog()
{
     _logger.LogError((int)LoggingEvents.LIST_ITEMS, "Test info #543434");
     return true;
}

Как лучше всего использовать регистратор в других моих слоях, таких как мой уровень доступа к данным?


person AdrienTorris    schedule 22.02.2016    source источник


Ответы (3)


Лучше всего использовать ILogger<T> только на уровне приложений (контроллеры, службы приложений, но не службы домена).

Если вы хотите добавить ведение журнала для ваших доменных служб/репозиториев, лучше всего создать для него декораторы. Это хорошо работает только в том случае, если вы абстрагировали свои интерфейсы от их реализаций и везде используете/внедряете интерфейсы).

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

Зачем избегать регистрации/внедрения вашего регистратора в службу?

Связь

Вам следует избегать внедрения ILogger<T> в объекты вашего домена, так как это связывает ваш домен с фреймворком/базовыми классами ведения журнала ASP.NET Core. Однако вы всегда можете определить свой собственный интерфейс регистратора, чтобы использовать его в своем домене и реализовать как оболочку вокруг ILogger<T>.

Твердый принцип

S в принципе SOLID означает SRP (Single Responsibility Principle) и гласит, что один объект должен иметь только одну и только одну ответственность. Выполнение ведения журнала и сохраняемости или бизнес-логики в одном объекте нарушает этот принцип.

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

person Tseng    schedule 22.02.2016
comment
«поскольку это связывает ваш домен с платформой/базовыми классами ведения журналов ASP.NET Core» — интерфейсы ILogger, включенные в ASP.NET Core, уже очень универсальны и открыты для других реализаций; здесь действительно нет большой связи. Он также находится в пространстве имен Extensions (не ASP.NET), так что это отдельный объект, и фактически считается, что он напрямую адаптирован в .NET Core. - person poke; 22.02.2016
comment
@poke: Верно, но если интерфейс когда-либо изменится, это сломает весь ваш домен. Когда у вас есть собственный интерфейс, он ломается только в том случае, если вы его модифицируете. Если интерфейсы регистратора .NET Core будут изменены, только ваша оболочка/поставщик вокруг него выйдет из строя, что не является проблемой, поскольку это инфраструктура и за пределами вашего домена. Но компания/разработчик должны решить, кто далеко загонит абстракцию :P - person Tseng; 22.02.2016

«Наилучшей практикой» было бы просто внедрить собственные регистраторы для каждого компонента и позволить каждому компоненту вести собственное журналирование.

Если вы считаете, что это становится слишком шумным для вашего приложения, вы можете изменить уровень детализации для частей пространства имен, чтобы вы получали, например, только Журналы уровня Information для ваших контроллеров и Warning (или хуже) для всего остального:

loggerFactory.AddConsole(new ConsoleLoggerSettings()
{
    Switches = new Dictionary<string, LogLevel>()
    {
        ["MyNamespace.Services"] = LogLevel.Warning,
        ["MyNamsepace.Controllers"] = LogLevel.Information
    }
});
person poke    schedule 22.02.2016
comment
Проголосовал за - не уверен, почему кто-то проголосовал за это? Я думаю, что это может улучшить ответ, упомянув, что он предполагает, что внедрение зависимостей будет использоваться и на других уровнях. - person Nicholas Blumhardt; 23.02.2016

Если вы хотите регистрировать необработанные исключения, вам, вероятно, следует добавить промежуточное программное обеспечение, которое может позаботиться об этом. Вы можете увидеть пример в этом ответе SO: https://stackoverflow.com/a/31054664/5795

person henningst    schedule 22.02.2016