3

我使用 S#arp Architecture,它使用 Windsor Castle 进行 IoC。我现在有了一个新控制器,与项目中的所有其他控制器不同,它需要相同接口的不同实现。即所有控制器都使用 ProductsRepository: IProductsRepository 作为实现,但新的控制器必须使用 SpecificProductsRepository。

如何配置它以自动识别和管理它?无论是纯 Windsor 方式,还是借助 ASP.NET MVC 帮助(例如在我的自定义控制器工厂中)。

好的,看起来我需要子容器。仍在搜索中。

4

2 回答 2

6

一种更简单、更简单的方法是使用 Windsor 的服务覆盖。

例如,像这样注册您的存储库:

container.Register(Component.For<IProductsRepository>
                     .ImplementedBy<ProductsRepository>()
                     .Named("defaultProductsRepository"),
                   Component.For<IProductsRepository>
                     .ImplementedBy<SpecificProductsRepository>()
                     .Named("specificProductsRepository"));

这将确保默认实现是ProductsRepository. 现在,对于您的特定控制器,添加一个服务覆盖,如下所示:

container.Register(Component.For<NewController>()
     .ServiceOverrides(ServiceOverride
          .ForKey("productsRepository")
          .Eq("specificProductsRepository"));

您可以在此处阅读文档。

编辑:如果您想使用 注册您的存储库AllTypes,您可以调整注册密钥,例如:

container.Register(AllTypes.[how you used to].Configure(c => c.Named(GetKey(c)));

例如,GetKey可能是这样的:

public string GetKey(ComponentRegistration registration)
{
    return registration.Implementation.Name;
}
于 2011-03-15T10:10:04.223 回答
0

好的,这些天我倾向于回答我自己的问题......所以这里是为那些需要它的人准备的。

     // create subcontainer with specific implementation
     var mycontainer = new WindsorContainer();
     mycontainer.Register(AllTypes.Pick()
        .FromAssemblyNamed("My.Data")
        .WithService.FirstInterface()
        .Where(x => x.Namespace == "My.Data.Custom")
        .Configure(x => x.LifeStyle.Is(LifestyleType.PerWebRequest)));
     container.AddChildContainer(mycontainer);

     ControllerBuilder.Current.SetControllerFactory(new ExtendedControllerFactory(
        new Dictionary<string, IWindsorContainer> { {"", container}, {"Lm", mycontainer} }));

控制器工厂根据名称选择合适的容器。最大的挑战是在请求结束时调用适当容器的 Release(controller),即记住哪个容器用于实例化控制器。但这可以通过几种方式解决,我想 - 记住线程特定(在 HttpContext 中),记住 BaseController 属性,记住内部字典等。

于 2011-03-15T09:37:49.663 回答