与其他 IoC 容器(Windsor、Spring.Net、Autofac ..)相比,使用 Enterprise Library Unity 的优缺点是什么?
8 回答
我正在为一个用户组准备一个演示文稿。因此,我刚刚经历了一堆。即:AutoFac、MEF、Ninject、Spring.Net、StructureMap、Unity 和 Windsor。
我想展示 90% 的案例(构造函数注入,这主要是人们使用 IOC 的主要目的)。 您可以在此处查看解决方案(VS2008)
因此,有几个关键区别:
- 初始化
- 对象检索
它们中的每一个也都有其他特性(有些具有 AOP 和更好的 gizmo,但通常我想要 IOC 做的只是为我创建和检索对象)
注意:不同库对象检索之间的差异可以通过使用 CommonServiceLocator 来消除:http: //www.codeplex.com/CommonServiceLocator
这给我们留下了初始化,它通过两种方式完成:通过代码或通过 XML 配置 (app.config/web.config/custom.config)。有的两者都支持,有的只支持一个。我应该注意:一些使用属性来帮助 IoC。
所以这是我对差异的评估:
忍者
仅代码初始化(带有属性)。我希望你喜欢 lambdas。初始化代码如下所示:
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>();
春天.NET
XML 仅据我所知。但是对于功能,Spring.Net 在阳光下可以做 IoC 可以做的所有事情。但是因为统一化的唯一方法是通过 XML,所以 .net 商店通常会避免使用它。虽然,很多 .net/Java 商店都使用 Spring.Net,因为 .net 版本的 Spring.Net 和 Java Spring 项目之间的相似性。
注意:现在可以通过引入Spring.NET CodeConfig在代码中进行配置。
温莎
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。
一个缺点是它相当新,所以它可能有老玩家已经解决的错误。
话虽如此,您可能想检查一下。
旧线程,但因为这是谷歌在我输入 unity vs spring.net 时向我展示的第一件事......
如果你不喜欢 XML 配置,Spring 现在会做 CodeConfig
http://www.springframework.net/codeconfig/doc-latest/reference/html/
此外,Spring 不仅仅是一个 DI 容器,如果您查看文档中的“模块”部分,DI 容器是它所做的大量事情的基础。
如果我弄错了,请纠正我,但我认为 Autofac 本身支持此链接中列出的 XML 配置:Autofac XML 配置
Spring 有一个特性,它可以根据参数名称或位置向构造函数或属性注入参数。如果参数或属性是简单类型(例如整数、布尔值),这将非常有用。请参阅此处的示例。我认为这并不能真正弥补 Spring 无法在代码中进行配置的原因。
Windsor 也可以做到这一点,并且可以在代码而不是配置中做到这一点。(如果我错了,请纠正我,我只是通过我在这里听到的内容)。
我想知道Unity是否可以做到这一点。
需要注意的一点:Ninject 是唯一支持上下文依赖注入的 IoC 容器(根据他们的网站)。但是,因为我没有使用其他 IoC 容器的经验,所以我无法判断这是否成立。
只是为了增加我的 2 美分,我尝试了 StructureMap 和 Unity。我发现 StructureMap 的文档记录很差/有误导性,配置起来很麻烦,而且使用起来很笨拙。同样,它似乎不支持解析时构造函数参数覆盖之类的场景,这对我来说是一个关键的使用点。所以我放弃了它并选择了 Unity,它在大约 20 分钟内完成了我想做的事情。
我个人使用 Unity,但只是因为它来自 Microsoft。我对这个决定感到遗憾有一个原因:它最大的问题是有一个大“错误”导致它不断抛出异常。您可以在调试时忽略异常。但是,如果您遇到它,它会极大地减慢您的应用程序,因为抛出异常是一项昂贵的操作。例如,我目前正在我的代码中的一个地方“修复”这个异常,Unity 的异常使页面的渲染时间增加了4 秒。有关更多详细信息和解决方法,请参阅: