对于特定的控制器,Windsor实例化不同的类

时间:2011-03-15 09:20:19

标签: asp.net-mvc castle-windsor ioc-container sharp-architecture

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

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

好像我需要子容器。还在寻找。

2 个答案:

答案 0 :(得分:6)

更简单,更简单的方法是使用Windsor的服务覆盖。

E.g。像这样注册你的回购:

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"));

您可以阅读文档here

修改:如果您想使用AllTypes注册您的存储库,则可以调整注册码,例如像这样:

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

其中GetKey例如可能是这样的:

public string GetKey(ComponentRegistration registration)
{
    return registration.Implementation.Name;
}

答案 1 :(得分: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(控制器),即记住哪个容器用于实例化控制器。但是我可以用几种方式解决这个问题 - 记住在线程特定的(在HttpContext中),记住在BaseController属性中,记住在内部字典中等等。