在下面的代码片段中,我们有一个根容器和一个子容器。子容器包含Person
的注册,该注册取决于根容器中定义的INameProvider
。 INameProvider
轮流取决于IInfoProvider
,它在两个容器中都有注册。
当要求子容器解析Person
的实例时,该机制使用根容器来解析INameProvider
的实例(如预期的那样),但也解析IInfoProvider
的实例1}}。我希望子容器中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 Web应用程序,其中常见的应用程序功能存储在根容器中,并且每个租户都有自己的子容器,其中某些内容被覆盖。例如,数据存储区的配置存储在每个子容器中(每个租户都有自己的数据库),而某些MVC控制器则不同。创建控制器时,我们使用Container.GetChildContainer
查找子容器并尝试解析我们需要的对象。我们的控制器间接依赖于数据存储配置,但永远不会使用子容器中定义的控件。