Допустим, (не обязательно с DI) у меня есть интерфейс, чтобы что-то делать, и два разных класса, реализующих его (делающие разные «что-то»):
public interface ISomethingDoer {
void DoSomething();
}
public class DoerOfSomethingExciting : IDoSomething { ... }
public class DoerOfSomethingBoring : IDoSomething { ... }
И у меня где-то есть метод, который используетISomethingDoers обоих типов:
public class DoerOfVariousThings {
...
public DoerOfVariousThings(ISomethingDoer excitingDoer, ISomethingDoer boringDoer)
{
...
}
public void DoVariousThings() {
this.excitingDoer.DoSomething();
this.boringDoer.DoSomething();
}
}
Но я хочу иметь возможность легко перекомпилировать все, что делается, в другом порядке:
public void DoVariousThings() {
this.excitingDoer.DoSomething();
this.boringDoer.DoSomething();
}
Я мог бы просто поменять эти две строки,и я сделал.Но то, что я хотел бы больше, это что-то похожее на следующее:
public class DoerOfVariousThings {
...
public DoerOfVariousThings(ISomethingDoer firstDoer, ISomethingDoer secondDoer)
{
...
}
public void DoVariousThings() {
this.firstDoer.DoSomething();
this.secondDoer.DoSomething();
}
}
Таким образом, с простым, не контейнерным, DI "по-своему", я мог бы внести изменения в составroot, а не в классе:
public void BuildRoot() {
// The change can be made by slightly modifying the following two lines
ISomethingDoer firstDoer = new DoerOfSomethingExciting();
ISomethingDoer secondDoer = new DoerOfSomethingBoring();
var variousDoer = new DoerOfVariousThings(firstDoer, secondDoer);
...
}
Но как мне точно поддерживать такие же вещи с помощью DI на основе контейнеров?В частности, я пытаюсь использовать SimpleInjector, но более общие ответы или ответы для разных структур также могут быть полезны.
Очевидно, я мог бы зарегистрировать две конкретные реализации ISomethingDoer
как конкретные классы, а не как реализации интерфейса, ноэто кажется неоптимальным: если я правильно понимаю, либо конструктору DoerOfVariousThings
придется взять эти конкретные классы вместо их интерфейса, либо я бы внес изменение в корень композиции, изменив порядок параметров конструктора DoerOfVariousThings
чем путем изменения обновления объектов, которые заполняют эти параметры.
На самом деле, я думаю, мне бы хотелось что-то вроде следующего (воображаемый синтаксис):
using (var container = ...) {
container.Register<ISomethingDoer, DoerOfSomethingExciting>("first");
container.Register<ISomethingDoer, DoerOfSomethingBoring>("second");
...
}
...
[DIParamMap("first", firstDoer)]
[DIParamMap("second", secondDoer)]
public DoerOfVariousThings(ISomethingDoer firstDoer, ISomethingDoer secondDoer) {
...
}
МожетЯ делаю что-то подобное?Или что-то лучше для такого сценария?Если да, то как?Спасибо.