Корни динамической конфигурации? На основании вызова дб?

У меня есть приложение, которое при запуске знает достаточно, чтобы выбрать базу данных и вытащить объект конфигурации.

Затем он выполняется на этом объекте конфигурации, удаляет кучу вещей, вытягивает другой объект конфигурации, выполняет его и т. Д. В цикле.

Прямо сейчас у меня есть корень конфигурации в начале приложения, которое настраивает все, что может. Но так как он не знает всего до окончания вызова db, все ветви объекта после этой точки скрыты за фабриками фабрик, поэтому они могут обрабатывать любые конфигурации, находящиеся в объекте конфигурации.

У меня вопрос, это нормально? Кажется, что альтернативой было бы иметь два корня конфигурации или два контейнера DI. Один до, и один после вызова дб.

Если бы я мог сделать мой корень DI после вызова db, я мог бы связать вещи прямо в контейнер прямо там и таким образом удалить тонну фабрик из моего кода, которые существуют только потому, что при запуске приложения я не уверен, что будет нужно. Но это кажется странным. Это также означает, что мне придется воссоздавать свой контейнер или второй контейнер с каждой итерацией, что кажется очень странным.

РЕДАКТИРОВАТЬ: я только что обнаружил, что StructureMap имеет функцию вложенного контейнера почти для этого конкретного случая использования, поэтому я определенно кое-что здесь: http://structuremap.github.io/the-container/nested-containers/

РЕДАКТИРОВАТЬ: Я не получил никаких ответов, но позже смог ответить на этот вопрос. Добавил мой ответ ниже.

1 ответ

Получается, это довольно распространенный сценарий.

Первым шагом было признание того, что моя путаница возникла из-за того, что мое приложение подвергается рефакторингу, но пока не имеет четкой архитектуры pub / sub.

Как только это будет сделано, становится совершенно очевидно, что код, который запускает базу данных до и после публикации, действительно может рассматриваться как отдельные приложения.

На данный момент у меня есть в основном два варианта. Я могу рассматривать их как отдельные приложения, и в этом случае каждый из них получает свой собственный независимый root.

Или, в качестве альтернативы, я могу продолжить совместное использование кода между ними и использовать вложенные контейнеры.

Очевидно, что большинство IoC (я проверил Unity, StructureMap и WindsorCastle) имеют способы, с помощью которых вы можете передать родительский объект Container/Configuration в подпроект, а также клонировать и переопределить определенные регистрации, находясь в рамках этого проекта.

Таким образом, мой первоначальный проект может настраивать соединения с базой данных и протоколированием, и т. Д., А затем каждый из экземпляров подпроекта может расширять этот общий экземпляр конфигурации в соответствии с любыми данными, полученными в результате вызова базы данных.

Также оказывается, что IoC, который я использовал, SimpleInjector, не может это сделать. Хенси часть моего замешательства.