(Автоматический) Механизмы привязки к имплантации зависимостей
Два общих механизма для создания привязок инъекций зависимостей, например, через контейнер IOC, - это конфигурация XML или блок императивного кода. В этих случаях пара значений ключа является явной (т.е. Ключ = запрошенный тип, value = возвращаемый тип).
Тем не менее, существует третий "эвристический" подход, при котором контейнеру приложения /IOC присваиваются только ключи [IMyClass], и затем контейнер отображает множество зависимостей сборки приложения, чтобы найти все сопоставленные по конкретному классу конкретные классы [MyClass]. Говоря иначе, значения типа "возвращаемого типа" обнаруживаются, а не объявляются.
То, что я хотел бы знать, двоякое:
- Какие контейнеры МОК (или другие инструменты позднего связывания) допускают эвристический подход? Имеет ли этот подход более общее название?
- Существуют ли другие методы привязки, кроме трех перечисленных мной, которые используются на практике?
Ответы
Ответ 1
Это называется Конфигурация на основе Конвенции или Автоматическая регистрация и поддерживается этими контейнерами .NET DI:
Наиболее распространенными механизмами конфигурации, используемыми для контейнеров DI, являются
- XML
- Код как конфигурация
- Конфигурация на основе протокола
Четвертый, но необычный подход - использовать атрибуты. Managed Extensibility Framework является наиболее ярким примером такого подхода, который чаще встречается в Java.
Ответ 2
То, что вы называете "эвристическим" подходом, я называю условностями. Большинство контейнеров IoC позволяют вам переопределить способы их устранения, что означает, что вы можете ввести любое соглашение, которое вы хотите. Я не знаю таких соглашений по умолчанию, о которых я знаю. Скорее, большинство контейнеров ничего не делают по умолчанию; это ваша работа, чтобы сообщить им, как разрешать типы, либо через файл конфигурации, либо через код.
Пример пользовательского соглашения, который я нахожу, довольно распространен, что экономит много объявлений: если запрошенный тип - это тип интерфейса, начинающийся с "I" и заканчивающийся "Службой", тогда попытайтесь создать и разрешить тип с помощью одно и то же имя, кроме "Я". Это позволит автоматически разрешать имена, такие как IFooService
to FooService
. Кроме того, вы можете ввести логику для решения разных сервисов в разных контекстах довольно легко, и вы можете обрабатывать жизненные сроки экземпляра службы в общем месте.
Так как вы можете переопределить, как связывает большинство контейнеров IoC, вы можете ввести и другие варианты поведения. Однако, как правило, есть два варианта:
- Настроить во время выполнения (через файлы конфигурации, такие как файлы XML)
- Настроить во время компиляции (через декларативный DSL-подобный API или через пользовательские соглашения или другую форму пользовательской логики)
Ответ 3
Я обычно использовал то, что вы описали как настраиваемый шаг в конгигации. AFAIK нет контейнера, предоставляющего вне коробки такую стратегию (и, на мой взгляд, это не контейнерная часть, а материал конфигурации, который должен быть внешним от ответственности контейнера).
Ответ 4
Поскольку я использовал StructureMap совсем немного, я бы знал, как это сделать с этим контейнером: в основном это было бы соглашение о пользовательской регистрации (от инициализации или реестра, блок Scan-лямбда и найти метод "Конвенция" ).
Он позволяет вам просматривать отраженные типы, а затем вставлять их в конфигурацию контейнера по своему усмотрению. Он должен позволять то, что вы пытаетесь сделать.