Предоставленный вами код не является допустимым C# и не будет компилироваться. Вы не можете указать открытый общий тип внутри тегов ‹ и >. Вы должны указать закрытый общий тип. Однако допустимо следующее С#:
container.GetInstance(typeof(IWordFacade<,,,>));
Хотя это скомпилируется, это все равно не будет работать в Simple Injector (или любом другом DI-фреймворке), поскольку фреймворки всегда хотят вернуть вам конкретный экземпляр, но вы не можете создать экземпляр для открытого универсального типа, что совершенно очевидно. , так как открытый универсальный тип — это просто шаблон. Вам необходимо заполнить пустые поля, чтобы иметь возможность создать экземпляр. Другими словами, вам нужен закрытый универсальный тип.
Но как контейнер должен знать, какой закрытый универсальный экземпляр он должен создать с учетом этого открытого универсального типа? Существует бесконечное количество возможных перестановок.
Хотя вы можете зарегистрировать открытый универсальный тип следующим образом:
container.Register(typeof(IWordFacade<,,,>), typeof(WordImpl<,,,>));
Вам нужно будет запросить закрытый универсальный интерфейс для вашего контейнера DI, чтобы иметь возможность разрешить его:
container.GetInstance<IWordFacade<Foo, Bar, FooBar>>();
or
container.GetInstance(typeof(IWordFacade<Foo, Bar, FooBar>));
ОБНОВЛЕНИЕ
Из вашего обновления я понимаю, что вы либо регистрируете ConcreteFacade1
, либо ConcreteFacade2
, исходя из файла конфигурации, но никогда оба. Чтобы сделать это (в C#), вам нужен не универсальный интерфейс, иначе вы сможете программировать только с System.Object
, что не очень полезно (и безопасно для типов). Итак, пусть ваш универсальный IWordFacade<T1,T2,T3,T4>
наследуется от следующего неуниверсального интерфейса:
interface IWordFacade {
object DoSomething(object value);
}
Таким образом, вы можете сделать следующую регистрацию:
contianer.Register<IWordFacade, ConcreteFacade1>();
И вы можете решить:
container.GetInstance<IWordFacade>();
Или, конечно, внедрить IWordFacade
в конструктор другого типа.
Теперь вам нужно внедрить два метода в реализации. Если у вас есть несколько реализаций, полезно определить базовый класс. Этот базовый класс может реализовать необобщенный метод интерфейса:
public abstract class WordFacadeBase<T1, T2, T3, T4> : IWordFacade<T1, T2, T3, T4> {
public abstract T1 DoSomething(T2 value);
object IWordFacade.DoSomething(object value) {
return DoSomething(T2)value);
}
}
person
Steven
schedule
17.03.2014