企业图书馆Unity与其他IoC容器
使用Enterprise Library Unity与其他IoC容器(Windsor,Spring.Net,Autofac ..)有什么优点和缺点?
我正在准备一个用户组的演示文稿。 就这样,我刚刚经历了一堆。 即:AutoFac,MEF,Ninject,Spring.Net,StructureMap,Unity和Windsor。
我想展示90%的情况(构造函数注入,主要是人们使用IOC的原因)。 你可以看看这里的解决scheme(VS2008)
因此,有几个关键的区别:
- 初始化
- 对象检索
他们每个人都有其他的function(一些有AOP和更好的小玩意儿,但通常我希望一个国际奥委会要做的是为我创build和检索对象)
注意:通过使用CommonServiceLocator,可以抵消不同库对象检索之间的差异: http : //www.codeplex.com/CommonServiceLocator
这给我们留下了初始化,这通过两种方式完成:通过代码或通过XMLconfiguration(app.config / web.config / custom.config)。 有的支持两种,有的只支持一种。 我应该注意到:一些使用属性来帮助IoC。
所以这里是我对差异的评估:
Ninject
只有代码初始化(带有属性)。 我希望你喜欢lambda。 初始化代码如下所示:
IKernel kernel = new StandardKernel( new InlineModule( x => x.Bind<ICustomerRepository>().To<CustomerRepository>(), x => x.Bind<ICustomerService>().To<CustomerService>(), x => x.Bind<Form1>().ToSelf() ));
StructureMap
初始化代码或XML或属性。 v2.5也很lambda'y。 总而言之,这是我的最爱之一。 关于StructureMap如何使用Attributes的一些非常有趣的想法。
ObjectFactory.Initialize(x => { x.UseDefaultStructureMapConfigFile = false; x.ForRequestedType<ICustomerRepository>() .TheDefaultIsConcreteType<CustomerRepository>() .CacheBy(InstanceScope.Singleton); x.ForRequestedType<ICustomerService>() .TheDefaultIsConcreteType<CustomerService>() .CacheBy(InstanceScope.Singleton); x.ForConcreteType<Form1>(); });
统一
初始化代码和XML。 不错的库,但XMLconfiguration是一个痛苦的屁股。 伟大的图书馆为微软或公路商店。 代码初始化很简单:
container.RegisterType<ICustomerRepository, CustomerRepository>() .RegisterType<ICustomerService, CustomerService>();
Spring.NET
XML只有我可以告诉的附近。 但是对于Spring.Net来说,IoC可以完成所有function。 但是因为整合的唯一方式是通过XML,所以通常可以通过.net商店来避免。 尽pipe许多.net / Java商店使用Spring.Net是因为.net版本的Spring.Net和Java Spring项目之间的相似性。
注意 :通过引入Spring.NET CodeConfig,现在可以在代码中进行configuration。
温莎
XML和代码。 像Spring.Net一样,Windsor会做任何你想做的事情。 温莎可能是最受欢迎的IoC容器之一。
IWindsorContainer container = new WindsorContainer(); container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton); container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton); container.AddComponent<Form1>("Form1");
Autofac
可以混合使用XML和代码(v1.2)。 很好的简单的IoC库。 似乎没有太多的大惊小怪的做基础。 支持嵌套的容器,具有本地化的组件范围和定义良好的生命周期pipe理。
这是你如何初始化它:
var builder = new ContainerBuilder(); builder.Register<CustomerRepository>() .As<ICustomerRepository>() .ContainerScoped(); builder.Register<CustomerService>() .As<ICustomerService>() .ContainerScoped(); builder.Register<Form1>();
如果我今天不得不select:我可能会使用StructureMap。 它具有对C#3.0语言function的最佳支持,并且具有最大的初始化灵活性。
注意 :Chris Brandsma把他原来的答案写成了一篇博文 。
据我所见,他们几乎是相同的,除了一些实施细节在这里和那里。 Unity比竞争对手最大的优势就是它是由微软提供的,那里有很多公司害怕OSS。
一个缺点是它比较新,所以可能会有老玩家已经解决的错误。
话虽如此,你可能想检查一下 。
老线程,但是因为这是Google向我展示的第一件事情,当我inputunity和spring.net时…
如果你不喜欢XMLconfiguration,Spring现在可以做CodeConfig
http://www.springframework.net/codeconfig/doc-latest/reference/html/
而且,Spring不仅仅是一个DI容器,如果你看一下文档中的“Modules”部分,DI容器就是它所做的大量工作的基础。
纠正我,如果我错了,但我认为Autofac本身支持XMLconfiguration列在此链接: 自动configurationXMLconfiguration
Spring有一个特性,它可以根据参数名称或位置将参数注入到构造函数或属性中。 如果参数或属性是一个简单的types(例如一个整数,一个布尔值),这是非常有用的。 看到这里的例子 。 我不认为这真的弥补了Spring无法在代码中进行configuration。
温莎也可以做到这一点,并可以做代码不configuration。 (纠正我,如果我错了,我只是通过我听到的这里)。
我想知道Unity是否可以做到这一点。
有一点需要注意:Ninject是唯一支持上下文相关注入的IoC容器(按照他们的网站)。 但是,因为我没有其他IoC容器的经验,所以我不知道这是否成立。
为了增加我的2美分,我已经尝试了StructureMap和Unity。 我发现StructureMap被错误地logging下来,configuration上的痛苦,笨拙的使用。 同样,在parsing时,它似乎不支持像构造函数参数覆盖这样的场景,这对我来说是一个关键的使用点。 所以我放弃了,并且和Unity一起去了,并且在20分钟内做了我想要的。
我个人使用Unity,但只是因为它来自微软。 我对这个决定感到遗憾,原因之一是它对它的最大的一点是有一个大的“bug”,导致它不断抛出exception。 debugging时可以忽略exception。 然而,如果你运行它,它会极大地减慢你的应用程序,因为抛出一个exception是一个昂贵的操作。 例如,我目前正在“修复”这个exception,在我的代码中,Unity的exception会在页面的渲染时间中增加额外的4秒 。 有关更多详细信息和解决方法,请参阅:
可以使Unity一直不抛出SynchronizationLockException吗?