在非常有限的场景中,我需要从未知类型(在编译时)转到为该类型注册的对象的实例。
在大多数情况下,我使用类型化的工厂,我知道我想在编译时解析的类型...所以我将Func<IMyType>
注入构造函数
...但是在这些有限数量的场景中,为了避免直接调用容器(因此必须从库中引用Windsor,这是我想避免的反模式),我需要注入一个Func<Type,object>
...我想在内部容器。解析(类型)为Func的Type参数。
有没有人就最简单/最直接的设置方法提出一些建议?
我尝试了以下操作,但是通过这种设置,我最终完全绕过了常规的TypedFactoryFacility,这绝对不是我想要的:
Kernel.Register(Component.For(typeof (Func<Type, object>)).LifeStyle.Singleton.UsingFactoryMethod(
(kernel, componentModel, creationContext) =>
kernel.Resolve(/* not sure what to put here... */)));
提前感谢您的任何帮助。
答案 0 :(得分:3)
如果你记得你可以在温莎注册代表作为正常组件,这很容易:
container.Register(Component.For<Func<Type,object>>()
.Instance(t=>container.Resolve(t)));
您也可以通过类型工厂(如果您计划通过此工厂解决瞬态组件,建议的方法,因为类型化工厂为您提供范围)和custom selector来实现这一点。
container.Register(
Component.For<YourSelector>(),
Component.For<Func<Type,object>>().Lifestyle.Transient
.AsFactory(x=>x.SelectedWith<YourSelector>());
答案 1 :(得分:0)
我认为你可以使用这个http://commonservicelocator.codeplex.com/的公共服务定位器,我认为Ayende为http://ayende.com/blog/archive/2008/10/02/the-common-service-locator-library.aspx写了对Castle Windsor的支持。它基本上提供了一种解决依赖关系的方法,而不依赖于特定的容器(例如Windsor / Ninject等)。您最终会在您要解决的级别上依赖于公共服务定位器,但至少可以换出例如温莎到应用程序级别的Ninject,因此它可以用于不同的项目。
初始化:
ServiceLocator.SetLocatorProvider(() => { return new WindsorServiceLocator(_container); });
其中_container是您的IWindsorContainer,然后解决依赖关系:
ServiceLocator.Current.GetInstance<MyType>();
或
ServiceLocator.Current.GetAllInstances<MyType>();