Обновление: Есть ли способ добиться того, что я пытаюсь сделать, в рамках IoC, отличной от Windsor? Windsor отлично справится с контроллерами, но не решит ничего другого. Я уверен, что это моя вина, но я дословно следую учебнику, и объекты не разрешаются с внедрением ctor, они по-прежнему равны нулю, несмотря на выполнение регистров и разрешений. С тех пор я отказался от своего кода DI и сейчас использую ручную инъекцию, потому что проект чувствителен ко времени. Надеясь получить DI разработан до крайнего срока.
У меня есть решение, в котором есть несколько классов, реализующих один и тот же интерфейс.
В качестве простого примера: Интерфейс
public interface IMyInterface {
string GetString();
int GetInt();
...
}
Конкретные классы
public class MyClassOne : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
public class MyClassTwo : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
Теперь эти классы будут внедрены там, где это необходимо, в слои выше. им нравится:
public class HomeController {
private readonly IMyInterface myInterface;
public HomeController() {}
public HomeController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
public class OtherController {
private readonly IMyInterface myInterface;
public OtherController() {}
public OtherController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
Оба контроллера внедряются с одним и тем же интерфейсом.
Когда дело доходит до разрешения этих интерфейсов с помощью соответствующего конкретного класса в моем IoC, как мне отличить, что HomeController
нуждается в экземпляре MyClassOne
и OtherController
нужен экземпляр MyClassTwo
?
Как связать два разных конкретных класса с одним и тем же интерфейсом в IoC? Я не хочу создавать 2 разных интерфейса, так как это нарушает правило DRY и в любом случае не имеет смысла.
В замке Виндзор у меня было бы 2 строки вроде этой:
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());
Это не сработает, потому что я получу только копию MyClassTwo
, потому что она последняя зарегистрирована для интерфейса.
Как я уже сказал, я не понимаю, как я могу сделать это без создания конкретных интерфейсов для каждого конкретного объекта, поскольку это нарушает не только правила DRY, но и основы ООП. Как мне этого добиться?
Обновление на основе ответа Марка Полсена.
Вот моя текущая IoC, куда пойдут операторы .Resolve
? Я ничего не вижу в документации Windsor
public class Dependency : IDependency {
private readonly WindsorContainer container = new WindsorContainer();
private IDependency() {
}
public IDependency AddWeb() {
...
container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));
return this;
}
public static IDependency Start() {
return new IDependency();
}
}