企业库 Unity 与其他 IoC 容器 [关闭]
-
03-07-2019 - |
题
使用 Enterprise Library Unity 与其他 IoC 容器(Windsor、Spring.Net、Autofac ..)相比有何优缺点?
解决方案
我正在为用户组准备演示文稿。因此,我刚刚经历了其中的一些。即:AutoFac、MEF、Ninject、Spring.Net、StructureMap、Unity 和 Windsor。
我想展示 90% 的情况(构造函数注入,这主要是人们使用 IOC 的目的)。你可以在这里查看解决方案(VS2008)
因此,存在一些关键差异:
- 初始化
- 对象检索
它们中的每一个都有其他功能(有些有 AOP 和更好的小发明,但一般来说,我希望 IOC 做的就是为我创建和检索对象)
笔记:不同库对象检索之间的差异可以通过使用 CommonServiceLocator 来消除: http://www.codeplex.com/CommonServiceLocator
这让我们进行初始化,这通过两种方式完成:通过代码或通过 XML 配置 (app.config/web.config/custom.config)。有些同时支持两者,有些只支持其中之一。我应该注意的是:有些使用属性来帮助 IoC 进行。
所以这是我对差异的评估:
忍者
仅代码初始化(带有属性)。我希望你喜欢 lambda。初始化代码如下所示:
IKernel kernel = new StandardKernel(
new InlineModule(
x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
x => x.Bind<ICustomerService>().To<CustomerService>(),
x => x.Bind<Form1>().ToSelf()
));
结构图
初始化代码或 XML 或属性。v2.5 也非常 lambda'y。总而言之,这是我的最爱之一。关于 StructureMap 如何使用属性的一些非常有趣的想法。
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。不错的库,但是 XML 配置很麻烦。非常适合微软或高速公路商店的图书馆。代码初始化很简单:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
Spring.NET
XML 仅据我所知。但就功能而言,Spring.Net 可以完成 IoC 可以完成的所有工作。但由于唯一的统一方法是通过 XML,.net 商店通常会避免使用它。尽管如此,许多 .net/Java 商店都使用 Spring.Net,因为 Spring.Net 的 .net 版本和 Java Spring 项目之间很相似。
笔记:现在可以通过引入在代码中进行配置 Spring.NET 代码配置.
温莎
XML 和代码。与 Spring.Net 一样,Windsor 会做您希望它做的任何事情。Windsor 可能是最受欢迎的 IoC 容器之一。
IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");
奥特法
可以混合 XML 和代码(使用 v1.2)。不错的简单 IoC 库。似乎没有太多大惊小怪的基础知识。支持具有本地组件范围和明确定义的生命周期管理的嵌套容器。
以下是初始化它的方法:
var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
.As<ICustomerRepository>()
.ContainerScoped();
builder.Register<CustomerService>()
.As<ICustomerService>()
.ContainerScoped();
builder.Register<Form1>();
如果我今天必须选择:我可能会选择 StructureMap。它对C# 3.0语言特性有最好的支持,并且初始化方面最灵活。
笔记:Chris Brandsma 将他最初的答案变成了 博客文章.
其他提示
据我所知,它们几乎相同,除了一些实现细节之外。 Unity在竞争中的最大优势在于它是由微软提供的,有很多公司都害怕OSS。
一个缺点是它相当新,所以它可能有老玩家已经解决的错误。
话虽如此,你可能想要检查出来。
旧线程,但因为这是Google在我输入unity vs spring.net时向我展示的第一件事......
如果您不喜欢XML配置,Spring现在会执行CodeConfig
http://www.springframework.net/codeconfig/doc-latest /参考/ HTML /
另外,Spring不仅仅是一个DI容器,如果你看一下docs中的“Modules”部分,DI容器就是它所做的大量事情的基础。
如果我弄错了,请纠正我,但我认为Autofac本身支持此链接中列出的XML配置: Autofac XML配置
Spring有一个功能,它可以根据参数名称或位置为构造函数或属性注入参数。如果参数或属性是简单类型(例如整数,布尔值),这非常有用。请参见此处的示例。我不认为这真的弥补了Spring无法在代码中进行配置。
Windsor也可以这样做,并且可以在代码中进行配置。 (纠正我,如果我错了,我只是通过我在这里听到的内容)。
我想知道Unity是否可以做到这一点。
有一点需要注意:Ninject是唯一支持上下文依赖注入的IoC容器(根据其网站)。但是,因为我没有其他IoC容器的经验,所以我不知道这是否成立。
为了加上我的2美分,我尝试了StructureMap和Unity。我发现StructureMap很难/错误地记录,配置的屁股很痛苦,而且使用起来很笨拙。同样,它似乎不支持解析时的构造函数参数覆盖等场景,这对我来说是一个关键的使用点。所以我放弃了它,然后和Unity一起去了,并且在大约20分钟内完成了我想做的事。
我个人使用Unity,但仅仅因为它来自微软。我对这个决定感到后悔的原因之一是:它最大的反对意见有一个很大的“错误”。这导致它不断抛出异常。您可以在调试时忽略异常。但是,如果你遇到它,它会使你的应用程序极大地变慢,因为抛出异常是一项昂贵的操作。例如,我目前正在“修复”这个例外在我的代码中的一个位置,Unity的异常为页面的渲染时间增加了额外的 4秒。有关更多详细信息和解决方法,请参阅: