Эти две записи реестра в StructureMap идентичны?
Я хочу зарегистрировать синглтон-класс для соответствующего интерфейса. Я нашел два разных способа добиться этого:
Опция 1:
this.For<ISomeClass>()
.Use<SomeClass>()
.Singleton();
Вариант 2:
this.For<ISomeClass>()
.Use(c=>c.GetInstance<SomeClass>())
.Singleton();
this.ForConcreteType<SomeClass>()
.Configure
.Singleton();
Так эти два вызова идентичны или есть разница между ними? Очевидно, что вариант 1 гораздо более желателен из-за его краткости.
1 ответ
Результат будет идентичным, но второй пример выполняет дополнительный шаг. Это действительно маленький. Но чем проще синтаксис, тем лучше.
Первый пример говорит, что когда есть необходимость ISomeClass
выполнить это с SomeClass
, Если экземпляр был создан, используйте его. Если нет, создайте экземпляр.
Второй пример говорит, что когда есть необходимость ISomeClass
выполнить его, вызвав анонимную функцию, которая вернет реализацию ISomeClass
, Эта функция разрешает и возвращает экземпляр SomeClass
,
Учитывая объем работы, выполняемой скрытно, вызов еще одной анонимной функции не будет иметь большого значения.
Больше беспокойства вызывает то, как более сложный подход может сбить с толку других разработчиков и создать проблемы. Это не гипотетически. Я видел это, и это не очень красиво.
Разработчик, идущий за вами, может не понимать, как должен работать контейнер IoC, и все, что он может сделать, это следовать вашему примеру, пока не поймет его. Поэтому важно показать правильный пример, иначе они могут полностью упустить смысл. Я видел такие фабричные методы:
this.For<ISomeClass>()
.Use(c=> new SomeClass(
c.GetInstance<ISomethingElse>(),
c.GetInstance<ISomeOtherThing>(),
c.GetInstance<ITenMoreOfThese>()
));
Затем они начинают создавать подобные объекты, разрешать экземпляры и использовать регистрацию DI для внедрения экземпляров в объекты. Конечно, есть веские веские причины для этого. Но он может загрязнять ваш код IoC, пока не будет болезненно изменить зависимости класса, что является одной из проблем, которые должен был решить контейнер.
Это на самом деле снежки еще немного. Теперь разработчики не хотят трогать все более хрупкий и запутанный код IoC, поэтому они прекращают создавать новые классы, начинают втиснуть новые функциональные возможности в существующие методы и никогда ничего не реорганизуют. IoC, который должен облегчить рефакторинг и меньшие классы и интерфейсы, в итоге усложняет задачу. Это приводит к разного рода запахам и гниению нового кода.
Поэтому я бы рекомендовал подход "без разбитого окна" - использовать простейший синтаксис, соответствующий первоначальному замыслу IoC, - указывать, где это возможно, тип реализации для интерфейса вместо функции, которая разрешает и возвращает реализацию.