2012-12-06 65 views
4

我有一个如下面的界面,我注入到统一容器中。Unity Factory Injection

public interface IMyInstanceFactory 
{ 
    IEnumerable<IMyInstance> GetAll(); 
} 

所有IMyInstance运行时即他们可以引导程序中进行设置之前是已知的,可以从统一检索。我对IMyInstanceFactory具体实现如下:

public class MyInstanceFactory:IMyInstanceFactory 
{ 
    IUnityContainer _container; 

    public MyInstanceFactory(IUnityContainer container) 
    { 
     _container = container; 
    } 
    public IEnumerable<IMyInstance> GetAll() 
    { 
     return _container.ResolveAll<IMyInstance>(); 
    } 
} 

..和我的引导程序我做这样的事情:

container.RegisterType<IMyInstance,MyInstance1>; 
container.RegisterType<IMyInstance,MyInstance2>; 
container.RegisterType<IMyInstance,MyInstance3>; 
container.RegisterType<IMyInstanceFactory,MyInstanceFactory>; 

这解决一切美丽。然而,我不想依赖容器本身或者仅仅为此实现IMyInstanceFactory,有没有一种方法可以在不实施IMyInstanceFactory的情况下进行设置? Unity是否为此提供了一个设施?

这种东西..

container.RegisterType<IMyInstanceFactory,factory=>factory.GetAll()>().IsResolvedBy(unity.ResolveAll<IMyInstance>); 

我知道城堡能做到这一点,可以统一做同样的事情?

+0

如果这真的是你所有的工厂,为什么不直接使用统一容器呢?或者如果你不想让你的代码依赖于Unity,你可以使用IServiceLocator。 – cadrell0

+2

请不要使用ServiceLocator。在现代应用程序体系结构中这是[被认为是反模式](http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx)。 –

回答

2

a port of the Castle Windsor Typed Factory Facilities for Unity。它会生成你的界面的实现,并为你做ResolveAll

你的引导代码应该是这个样子:

container.RegisterType<IMyInstance,MyInstance1>("1"); 
container.RegisterType<IMyInstance,MyInstance2>("2"); 
container.RegisterType<IMyInstance,MyInstance3>("3"); 
container.RegisterType<IMyInstanceFactory>(new TypedFactory()); 

GetAll的通话将被转换为容器调用ResolveAll

该端口遵循与Windsor相同的约定。

+0

好的,但您如何注册实际的工厂? - 就像一个没有公共构造函数的类(并且你不想注册一个特定的实例) - 你如何注册一个Func ,以便容器可以在需要时从头开始创建对象。 – BrainSlugs83

+1

@ BrainSlugs83您可以通过使用'InjectionFactory'使用常规工厂 var container = new UnityContainer(); container.RegisterType (new InjectionFactory(c => Foo.Create())); IFoo foo = container.Resolve (); 公共类Foo:IFoo的 { 私人美孚(){} 公共静态美孚的Create(){ 返回 新的Foo(); } }' –

0

将容器传递给工厂没有任何问题,如果工厂以单例形式公开,这样可以很好地工作,以便获取实例不需要再次传递容器。

另一种选择是使用工厂中的服务定位器来解析容器,因为定位器是单身,这种方法类似于前者。

+0

如果你实施了一个基于容器的工厂,你应该注意你放置该工厂的地方。查看关于[基于容器的工厂]的段落(http://blog.ploeh.dk/2012/03/15/ImplementingAnAbstractFactory.aspx)。 –

+0

@SebastianWeber:即使工厂是由Composition Root组成的,您仍然需要从应用程序访问它。这就是为什么我提到一个单身人士。我不认为除了这三个之外还有其他选项:我提到的两个选择(一个依赖于容器的工厂,它作为一个独立工具而不是一个不依赖容器并直接访问服务定位器的瞬态工厂)和不切实际的(一个对集装箱有明确依赖性的瞬态工厂)。 –

+0

为什么要依赖容器的瞬态工厂不可解决?使工厂成为组合根内的私人类。从接口映射到该实现。 Unity在容器中注册自己。当你解决私有实现时,容器将被注入到它中。您的应用程序只依赖于工厂界面。完成。 –