Каков наилучший подход для использования log4net на разных уровнях в решении - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть решение для веб-API со следующими слоями.Мне нравится реализовывать в моем проекте расширение Unity Log4net, и я хочу использовать его на разных уровнях.

  • DL
  • BL
  • Web (содержит классы контроллера и использует Unityдля IOC)

Нужно ли устанавливать пакет log4net только в веб-слой, который является главной точкой входа?или он должен быть установлен во всех слоях?

1 Ответ

0 голосов
/ 17 ноября 2018

Только Web (точка входа в приложение) действительно должна ссылаться на зависимость третьей части

Как я объясняю в одном из ваших предыдущих вопросов.

Создайте основной проект для своего пользовательского регистратора

public interface ILogger {
    //...
}

Все остальные проекты будут ссылаться на этот проект кода и использовать абстракцию ведения журнала.

Например, следующее находится на уровне данных

public class ExampleRepository : IRepository {
    private readonly ILogger logger;

    public ExampleRepository(ILogger logger){
        this.logger = logger;
    }

    //...use logger
}

Слой данных не должен ссылаться на внешнюю зависимость, поскольку он опирается только на пользовательскую абстракцию.

Далее, скажем, бизнес-уровень имеет следующий сервис

public class ExampleService: IService {
    private readonly ILogger logger;
    private readonly IRepository repository;

    public ExampleService(IRepository repository, ILogger logger){
        this.logger = logger;
        this.repository = repository;
    }

    //...use logger and repository
}

Бизнес-уровню не нужно ссылаться на внешнюю зависимость, поскольку он также опирается только на пользовательские абстракции.

На высшем уровне веб-проект. Опять предполагая простой контроллер

public class ExampleController: Controller {
    private readonly ILogger logger;
    private readonly IService service;

    public ExampleController(IService service, ILogger logger){
        this.logger = logger;
        this.service = service;
    }

    //...use logger and service
}

Во всем этом примере все классы зависят от абстракций, а не от проблем реализации.

Вы хотите использовать log4net в качестве реализации ведения журнала для всей системы, чтобы веб-проект ссылался на необходимые зависимости и затем создавал

public class Log4NetWrapper : ILogger {
    private readonly ILog log; //log4net 

    public Log4NetWrapper(ILog log) {
        this.log = log;
    }

    public void LogMessage(string msg) {
        log.Info(msg);
    }

    //...
}

На данный момент только веб-проект должен ссылаться на стороннюю зависимость.

Теперь каждый раз, когда зависимый класс хочет использовать ведение журнала, это должно быть сделано через log4net.

Отлично, в корне композиции веб-проекта вы регистрируете абстракцию и реализацию вместе со всеми расширениями, необходимыми для использования log4net.

container = new UnityContainer();
container.AddNewExtension<Log4NetExtension>();
container.RegisterType<ILogger, Log4NetWrapper>(new HierarchicalLifetimeManager());

Так что теперь, когда когда-либо потребуется ExampleController из контейнера, Log4NetWrapper будет внедрен во весь граф объектов, который в данный момент выполняется в веб-проекте.

В этом сценарии log4net является проблемой реализации. Из-за вышеупомянутого дизайна все участвующие классы связаны только с абстракциями, а не с конкрецией.

Короче говоря,

Нужно ли устанавливать пакет log4net только в веб-слое, который является главной точкой входа?

YES

или он должен быть установлен во всех слоях?

Если ваша архитектура разработана правильно, то НЕТ .

DI используется на протяжении всего этого примера. При правильном проектировании только корень композиции должен знать о любых внешних зависимостях.

...