Ответ 1
Да, было бы нормально зарегистрировать компоненты без их интерфейсов, но не по той причине, что вы даете.
Конкретные зависимости
Может случиться, что компоненты зависят от конкретных классов. Например, с потребителями Entity Framework должны быть введены ObjectContext в них. Это конкретный класс, который все еще нужно вводить, поскольку он должен быть общим между несколькими потребителями.
Таким образом, с учетом конструктора потребителя:
public FooRepository(FooObjectContext objectContext)
вам нужно настроить контейнер следующим образом:
container.Register(Component.For<FooObjectContext>());
FooRepository не требует интерфейса, поэтому нет смысла регистрировать интерфейс (даже если он доступен), но вы все равно должны регистрировать конкретный класс, потому что Windsor может разрешать типы явно зарегистрированных.
Интерфейсы только с одной реализацией
Тогда как насчет интерфейсов только с одной реализацией? Опять же, потребитель решает требования.
Представьте, что у потребителя есть этот конструктор:
public Ploeh(IBar bar)
Единственный способ, которым Замок Виндзор сможет решить Плоэ, - это когда вы регистрируете IBar. Даже если Bar является единственной реализацией IBar, это не будет работать:
container.Register(Component.For<Bar>());
Это не работает, потому что IBar никогда не регистрируется. Castle Windsor не заботится о том, что Bar реализует IBar, потому что он не хочет пытаться быть умным от вашего имени. Вы должны сказать это явно:
container.Register(Component.For<IBar>().ImplementedBy<Bar>());
Этот отображает IBar в Bar.
Регистрация как интерфейсов, так и конкретных типов
Тогда что, если вы хотите разрешить как конкретный тип, так и интерфейс?
Проблема с предыдущим примером заключается в том, что он позволит вам разрешить IBar, но не Bar.
Вы можете использовать метод Forward или многогенерическую перегрузку For для переадресации:
container.Register(Component.For<Bar, IBar>().ImplementedBy<Bar>());
Это позволяет вам разрешать как Bar и IBar.