城堡温莎弱型工厂

时间:2011-01-08 23:38:36

标签: c# .net dependency-injection castle-windsor

在非常有限的场景中,我需要从未知类型(在编译时)转到为该类型注册的对象的实例。

在大多数情况下,我使用类型化的工厂,我知道我想在编译时解析的类型...所以我将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... */)));

提前感谢您的任何帮助。

2 个答案:

答案 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>();