Интерфейсы ввода и регистрации
Мне было интересно, какие из лучших практик были связаны с каротажами и протоколированием фреймворков и инъекциями зависимостей. В частности, если я разрабатываю класс, который нуждается в способе регистрации, как мне нужно получить интерфейс для входа в журнал, чтобы сохранить инъекцию зависимостей?
Инъекция зависимостей, как представляется, указывает, что внешние зависимости должны быть введены извне (конструкторы или конструкторы свойств), поэтому следует взять экземпляр ILog в конструкторе и использовать его в классе? Должен ли я рассмотреть возможность регистрации дополнительной зависимости и получить ее в сеттер? Я нажимаю на слишком большую гибкость, позволяя изменить интерфейс ведения журнала, и должен ли я просто зависеть от конкретного интерфейса ведения журнала (например, создать статическую переменную ILog посредством вызова метода factory)? Может ли этот метод factory вызывать в контейнер, чтобы получить реализацию ILog, или это создаст конфликты инициализации инициализации статических переменных и инициализируется контейнер IoC?
Должен ли я делать это:
public class MyService : ISomeService
{
private static readonly ILogger s_log =
LoggingFactory.GetLogger(typeof(MyService))
...
}
или, возможно, это:
public class MyService : ISomeService
{
protected virtual ILogger Logger {get; private set;}
public MyService(ILogger logger, [other dependencies])
{
Logger = logger;
}
}
или даже это:
public class MyService : ISomeService
{
public virtual ILogger Logger {get; set;}
public MyService()
{
}
}
Другие шаблоны или способы сделать это? Что там делают люди? Что работает и когда?
Ответы
Ответ 1
Замечательно, что вы смотрите на инверсию управления и зависимость-инъекции.
Но для вашего вопроса есть еще одна концепция, которую вы, возможно, захотите изучить: аспектно-ориентированное программирование.
В .NET существуют некоторые хорошие рамки для выполнения аспектно-ориентированного программирования, в том числе Castle, LinFu и Microsoft Application Application Block. Фактически, некоторые контейнеры с инверсией контроля имеют в них также некоторые аспектно-ориентированные функции.
Эти концепции и инструменты помогают сделать такие проблемы, как ведение журнала, занять место с точки зрения кодового шума и автоматически обрабатываться.
Ответ 2
Мой совет? Оберните интерфейсы ведения журнала в свои собственные. Я принял зависимость от Log4Net один раз, сожжен и должен был реорганизовать много моих проектов из-за этого.
Ответ 3
Это не будет полным ответом, но одно соображение будет заключаться в том, что если вы введете свой ILog через конструктор вашего класса, вы можете затем издеваться над этой базой ведения журнала для тестирования вашего устройства. Другие мысли... Узел свойств для передачи в ILog означает, что вы не можете регистрировать действия из конструктора. Кроме того, вы не знаете наверняка, имеет ли ваш экземпляр доступ к ILOG, что означает, что вы должны обернуть каждый вызов тестом на действительный экземпляр ILog.
Ответ 4
Я хотел бы вводить его и использовать интерфейс. Главным образом для облегчения тестирования. Сделать легче заменить макет или заглушку при тестировании объекта-потребителя.
Я бы основывался на том, использовал ли я конструктор или инсталлятор установки для важности журнала для класса-потребителя. Если вы хотите, чтобы это было критическим, я бы предпочел бы впрыск конструктора, если это необязательно, тогда setter.
Я не вижу, где использование метода factory не может работать с контейнером, однако он затем тестирует потребительский класс в зависимости от правильной конфигурации этого метода factory.