Если у вас есть две разные реализации одного и того же интерфейса, которые нельзя обрабатывать одинаково, это запах кода. Часто задаваемые вопросы о способах обхода этой проблемы , но краткий ответ: , вы не сможете буквально указать два разных экземпляра одного и того же интерфейса, как это, без некоторой ручной работы. Не существует механизма для легкого подключения, потому что это проблема дизайна.
Найдите время, чтобы прочитать FAQ , чтобы узнать, почему и дополнительные идеи о том, как решить эту проблему, помимо того, чтоЯ показываю здесь.
Однако, давайте предположим, что вы не можете изменить интерфейс IDependency
, поскольку обычно это является камнем преткновения для людей.Давайте также предположим, что вы не можете просто поместить DependencyOne
и DependencyTwo
прямо в конструктор по ... любой причине.(И то, и другое было бы первым местом, где я бы попытался решить эту проблему, а не пытался усложнить мою работу с DI, но, опять же, скажем, ради аргумента, что это не вариант.)
Iвероятно, зарегистрирует каждый экземпляр в config с ключом метаданных, который можно будет использовать позже.
{
"components": [{
"type": "MyAssembly.DependencyOne, MyAssembly",
"services": [{
"type": "MyAssembly.IDependency, MyAssembly"
}],
"metadata": [{
"key": "type",
"value": "One",
"type": "System.String, mscorlib"
}]
}, {
"type": "MyAssembly.DependencyTwo, MyAssembly",
"services": [{
"type": "MyAssembly.IDependency, MyAssembly"
}],
"metadata": [{
"key": "type",
"value": "Two",
"type": "System.String, mscorlib"
}]
}]
}
ОК, поэтому у нас есть два компонента, каждый из которых предоставляет один и тот же интерфейс, и каждый из них имеет ключ метаданных One
или Two
соответственно.
В вашем классе вы можете использовать эти метаданные.
public class SomeService
{
readonly IEnumerable<Meta<IDependency>> _dependencies;
public SomeService(IEnumerable<Meta<IDependency>> dependencies)
{
_dependencies = dependencies;
}
public void DoSomething(string parameter)
{
var dep = _dependencies.First(a => a.Metadata["type"].Equals(parameter));
dep.DoSomething();
}
}
Идея состоит в том, что вы можете выбрать подходящую вещь, используя метаданные.Очевидно, приспособить это к вашим собственным потребностям;возможно, это не параметр от вызывающей стороны, а что-то в вашем коде в другом месте;концепция остается в силе.
Опять же, я не могу рекомендовать достаточно сильно, чтобы вы ознакомились с FAQ и настоятельно рассмотрели возможность редизайна, чтобы полностью избежать этой ситуации ,В конечном итоге это облегчит вашу жизнь и жизнь ваших коллег-разработчиков.