我使用S#arp架构,它将Windsor Castle用于IoC。我现在有一个新的控制器,与项目中的所有其他控制器不同,需要不同的相同接口实现。即所有控制器都使用ProductsRepository:IProductsRepository作为实现,但新的控制器必须使用SpecificProductsRepository。
如何将其配置为自动识别和管理?无论是纯粹的Windsor方式,还是ASP.NET MVC帮助(例如在我的自定义控制器工厂中)。
好像我需要子容器。还在寻找。
答案 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属性中,记住在内部字典中等等。