Может ли Виндзор взаимодействовать с другим контейнером IoC?

В основе нашего приложения мы используем Castle Windsor для управления нашими зависимостями. Мы будем загружать плагины от третьих лиц, которые могут использовать свои собственные контейнеры IoC. Мы бы хотели, чтобы они могли получать зависимости от ядра, например посредством внедрения в конструктор основных сервисов, но также получают зависимости от своего собственного контейнера IoC.

Похоже, что если бы они предоставили интерфейс поставщика услуг, Виндзор мог бы использовать его для разрешения неизвестных зависимостей, игнорируя результаты (поскольку время жизни этих компонентов - это чье-то дело) и продолжать работу.

Но я также уверен, что есть некоторые тонкости, которые возникают, когда вы пытаетесь сделать что-то подобное.


person Sebastian Good    schedule 13.05.2011    source источник
comment
Это очень плохая идея. Смешивание контейнеров похоже на смешивание спиртов - оно никогда не заканчивается хорошо.   -  person Krzysztof Kozmic    schedule 13.05.2011
comment
Это, конечно, вызывает похмелье, но, конечно, мы не первое приложение, которое хочет использовать один контейнер, но подружиться с библиотеками, которые выбрали другой.   -  person Sebastian Good    schedule 13.05.2011
comment
Похоже, здесь мы пытаемся решить ту же проблему. Прочтите это сообщение: stackoverflow.com/questions/6238431/common-service-registry. Удалось найти решение?   -  person Lawrence Wagerfield    schedule 05.06.2011


Ответы (1)


В этом нет необходимости. Если вы разрешите этим плагинам использовать Constructor Injection для получения соответствующих услуг из вашего хост-приложения, Castle Windsor сможет правильно подключить плагин. Плагины просто используют внедрение конструктора как способ статического объявления зависимости, так что, пока Windsor может разрешить зависимость, плагин получит ее.

То, что происходит внутри каждого подключаемого модуля (включая использование других контейнеров), не имеет значения для хост-приложения.

person Mark Seemann    schedule 13.05.2011
comment
Но эти программисты могут пожелать использовать IoC для регистрации своих собственных внутренних зависимостей, о которых ядро ​​IoC никогда не слышало. - person Sebastian Good; 13.05.2011
comment
MEF решает этот тип проблемы с помощью атрибутов. Если такой сценарий надстройки является основным для вашего приложения, он подойдет лучше. - person Mark Seemann; 13.05.2011
comment
На самом деле проблема в том, что даже если мы все добросовестны и используем внедрение конструктора для получения наших зависимостей, у нас возникает ситуация, когда ни один контейнер не знает обо всех этих зависимостях, поэтому не может создать объект. Я не мог написать конструктор для MyThing (ICoreService s, IMyPluginService p), поскольку основной контейнер мог удовлетворять s, а не p, и наоборот для контейнера плагина. - person Sebastian Good; 13.05.2011
comment
Это не обязательно будет иметь место с MEF, поскольку он не использует конфигурацию, а скорее обнаружение. Пока есть [Экспорт], который может удовлетворить [Импорт], они будут сопоставлены. - person Mark Seemann; 13.05.2011
comment
Конечно, но тогда мы используем MEF повсюду - вернемся к одному контейнеру, чтобы управлять ими всеми. Вопрос был об использовании нескольких контейнеров. Я тупой? - person Sebastian Good; 13.05.2011
comment
Я думаю, что это будет очень редкий случай, когда плагину потребуется ранее неизвестная зависимость, которую он не может удовлетворить сам. Однако, если это так, вы всегда можете предоставить конфигурацию Windsor для этого конкретного компонента в конфигурации XML. Это было бы возможно без перекомпиляции основного приложения. - person Mark Seemann; 13.05.2011
comment
Вы также можете использовать некоторые из новых (очень похожих на MEF) функций сканирования каталогов Castle Windsor в сочетании с некоторыми соглашениями и (опять же) Injection Constructor Injection в подключаемых модулях для поддержки этого сценария. - person Mark Seemann; 13.05.2011
comment
В любом случае, как бы вы на это ни смотрели, основное приложение эффективно контролирует контракт надстройки. Вероятно, уже требуются плагины для реализации определенного интерфейса или унаследованных от базового класса. Что такого проблемного в расширении этого контракта, чтобы также указать, что если вам нужны какие-либо услуги, которыми вы сами не владеете, вы можете запросить их через Constructor Injection? Это не мешает им использовать другой контейнер внутри, если они этого хотят, но сохраняет это использование как чистую деталь реализации, которая не просачивается из плагина. - person Mark Seemann; 13.05.2011
comment
Ядро может волшебным образом автоматически обнаруживать исполнителей ICoreInterface. Автор плагина построил HisInterestingImplementation с аргументами конструктора IAnotherCoreService и ISomeServiceOnlyFoundInThisPlugin. Основной контейнер IoC мог бы внедрить экземпляр IAnotherCoreService, но не знал бы, как удовлетворить ISomeServiceOnlyFoundInThisPlugin. Либо мы предоставляем плагину возможности регистрации, либо просим плагин предоставить нам средства разрешения. - person Sebastian Good; 18.05.2011
comment
Остерегайтесь этого - похоже, что это приведет к анти-шаблону Service Locator. Вот почему MEF использует механизм обнаружения вместо явной конфигурации. - person Mark Seemann; 18.05.2011
comment
Согласен, мне не кажется, что есть очень элегантный ответ, но я был немного удивлен, увидев так мало обсуждения по этой теме. - person Sebastian Good; 18.05.2011