Это в порядке для регистрации компонентов в Виндзоре, не указывая интерфейс?

Это считают невоспитанностью для регистрации компонентов в Виндзоре, не указывая интерфейс? т.е.

container.Register(Component.For<MyClass>().LifeStyle.Transient);

в противоположность...

container.Register(Component.For<IMyClass>().ImplementedBy<MyClass>().LifeStyle.Transient);

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

16
задан Kenny Evitt 21 July 2015 в 14:33
поделиться

1 ответ

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

Конкретные зависимости

Может случиться так, что компоненты зависят от конкретных классов. Например, с Entity Framework потребителям следует внедрить в них ObjectContext. Это конкретный класс, который все еще необходимо внедрить, потому что он должен быть общим между несколькими потребителями.

Таким образом, учитывая такой конструктор потребителя:

public FooRepository(FooObjectContext objectContext)

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

container.Register(Component.For<FooObjectContext>());

FooRepository не запрашивает интерфейс , поэтому нет смысла регистрировать интерфейс (даже если один был доступен), но вы все равно должны зарегистрировать конкретный класс, потому что Windsor может разрешать только типы, явно зарегистрированные .

Интерфейсы только с одной реализацией

А как насчет интерфейсов только с одной реализацией? И снова потребитель решает свои требования.

Представьте, что у потребителя есть этот конструктор:

public Ploeh(IBar bar)

Единственный способ, которым Castle Windsor сможет разрешить Ploeh, - это зарегистрировать IBar.Даже если Bar - единственная реализация IBar, это не сработает :

container.Register(Component.For<Bar>());

Это не работает, потому что IBar никогда не регистрируется. Castle Windsor не заботится о том, чтобы Bar реализовал IBar, потому что он не хочет действовать от вашего имени. Вы должны указать это явно:

container.Register(Component.For<IBar>().ImplementedBy<Bar>());

Это отображает IBar в Bar.

Регистрация и интерфейсов, и конкретных типов

А что, если вы хотите иметь возможность разрешать и конкретный тип, и интерфейс?

Проблема с предыдущим примером заключается в том, что он позволит вам разрешить IBar, но не Бар.

Вы можете использовать метод пересылки или многоуровневую перегрузку For для пересылки регистраций:

container.Register(Component.For<Bar, IBar>().ImplementedBy<Bar>());

Это позволяет разрешить как Bar, так и IBar.

27
ответ дан 30 November 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: