во фрагменте кода ниже у нас есть корневой контейнер и один дочерний контейнер.Дочерний контейнер содержит регистрацию для Person
, которая зависит от INameProvider
, определенного в корневом контейнере.INameProvider
в свою очередь зависит от IInfoProvider
, который имеет регистрацию в обоих контейнерах.
Когда дочернему контейнеру предлагается разрешить экземпляр Person
, механизм использует корневой контейнер для разрешения экземпляра INameProvider
(как и ожидалось), но также для разрешения экземпляра IInfoProvider
,Я ожидаю, что регистрация для IInfoProvider
в дочернем контейнере переопределит регистрацию в корневом контейнере.
WindsorContainer rootContainer = new WindsorContainer();
// register components for root container
rootContainer.Register(
Castle.MicroKernel.Registration.Component.For<IInfoProvider>().
ImplementedBy<InfoProvider>().
LifeStyle.Transient);
rootContainer.Register(
Castle.MicroKernel.Registration.Component.For<INameProvider>().
ImplementedBy<BobNameProvider>().
LifeStyle.Transient);
// create child container
WindsorContainer childContainer = new WindsorContainer();
rootContainer.AddChildContainer(childContainer);
// register components for child container
childContainer.Register(
Castle.MicroKernel.Registration.Component.For<Person>().
LifeStyle.Transient);
childContainer.Register(
Castle.MicroKernel.Registration.Component.For<INameProvider>().
ImplementedBy<JimNameProvider>().
LifeStyle.Transient);
var person = childContainer.Resolve<Person>();
Debug.Assert(person.ToString() == "Jim"); // <- fails, because person.ToString is "Bob"
Более того, если мы используем дочерний контейнер для разрешения экземпляра INameProvider
(как в фрагменте ниже), дочерний контейнер будет , используемый для получения экземпляра IInfoProvider
.Это то, чего я ожидаю.
var np = childContainer.Resolve<INameProvider>();
np.ToString() // <-- equals "Jim"
Кто-нибудь может объяснить, почему в первом примере используется корневой контейнер для разрешения IInfoProvider
вместо дочернего контейнера?
Возможно, есть лучший шаблон для обработки различных уровней регистрации компонентов, которые могут быть переопределены?
Обновление # 1 Реальная ситуация, с которой мы имеем дело, заключается в следующем.Мы разрабатываем мультитенантное веб-приложение MVC, в котором общие функциональные возможности приложения хранятся в корневом контейнере, и у каждого арендатора есть собственный дочерний контейнер, в котором определенные вещи переопределяются.Например, конфигурация хранилища данных хранится в каждом дочернем контейнере (у каждого арендатора есть своя собственная база данных), а некоторые контроллеры MVC отличаются.Когда контроллер создан, мы ищем дочерний контейнер с помощью Container.GetChildContainer
и пытаемся разрешить нужные нам объекты.Наш контроллер имеет косвенную зависимость от конфигурации хранилища данных, но тот, который определен в дочернем контейнере, никогда не используется.