Это тоже раздражает - это не СУХОЙ
Это правда. Но вы можете сделать так много для сквозной заботы, которая пронизывает все ваши типы. Вы должны использовать регистратор везде, поэтому вы должны иметь свойство для этих типов.
Итак, давайте посмотрим, что мы можем с этим поделать.
Singleton
Одиночки ужасны <flame-suit-on>
.
Я рекомендую придерживаться внедрения свойств, как вы сделали со вторым примером. Это лучший факторинг, который вы можете сделать, не прибегая к магии. Лучше иметь явную зависимость, чем скрывать ее через синглтон.
Но если синглтоны сэкономят вам значительное время, включая весь рефакторинг, который вам когда-либо придется делать (время хрустального шара!), Я полагаю, вы могли бы жить с ними. Если когда-либо было использование для Синглтона, это могло бы быть этим. Имейте в виду, что стоимость, если вы когда-либо захотите изменить свое мнение, будет примерно такой же высокой, как и она.
Если вы сделаете это, проверьте ответы других людей, используя шаблон Registry
(см. Описание), и тех, кто регистрирует (переустанавливаемый) синглтон фабрика , а не синглтон Экземпляр регистратора.
Существуют и другие альтернативы, которые могут работать так же хорошо, без особых компромиссов, поэтому вам следует сначала их проверить.
Фрагменты кода Visual Studio
Вы можете использовать Фрагменты кода Visual Studio , чтобы ускорить ввод этого повторяющегося кода. Вы сможете набрать что-то вроде logger
tab , и код волшебным образом появится для вас.
Использование AOP для СУШКИ
Вы могли бы немного убрать этот код внедрения свойства, используя среду Aspect Oriented Programming (AOP), такую как PostSharp , для автоматической генерации некоторых из них.
Когда вы закончите, это может выглядеть примерно так:
[InjectedLogger]
public ILogger Logger { get; set; }
Вы также можете использовать пример кода трассировки их метода для автоматической трассировки кода входа и выхода метода, что может устранить необходимость добавлять все свойства регистратора вместе. Вы можете применить атрибут на уровне класса или в пространстве имен:
[Trace]
public class MyClass
{
// ...
}
// or
#if DEBUG
[assembly: Trace( AttributeTargetTypes = "MyNamespace.*",
AttributeTargetTypeAttributes = MulticastAttributes.Public,
AttributeTargetMemberAttributes = MulticastAttributes.Public )]
#endif