对于特定的控制器,Windsor实例化不同的类别
-
24-10-2019 - |
题
我使用使用温莎城堡进行IOC的S#ARP体系结构。现在,我有了一个新的控制器,与项目中的所有其他控制器不同,需要对同一接口的不同实现。即所有控制器都使用products repository:iProductsrepository作为实现,但是新的必须使用特定的产品。
如何配置它以自动识别和管理此问题?以纯Windsor的方式,或使用ASP.NET MVC帮助(例如,在我的定制控制器工厂中)。
好的,好像我需要子框架。仍在搜索中。
解决方案
更简单,更简单的方法是使用温莎的服务覆盖。
例如,像这样注册您的存储库:
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;
}
其他提示
好的,这些天我倾向于回答自己的问题……所以对于那些需要它的人来说。
// 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} }));
控制器工厂根据名称选择合适的容器。最大的挑战是在请求结束时调用适当的容器的释放(控制器),即记住哪个容器用于实例化控制器。但这可以通过我想的几种方式解决 - 记住在特定于线程的(在httpcontext中),请记住在basecontroller属性中,在内部字典中记住,等等。
不隶属于 StackOverflow