企业库与其他 IoC 容器的统一

与其他 IoC 容器(Windsor、 Spring.Net、 Autofac. .)相比,使用 Enterprise Library Unity 有哪些优点和缺点?

55354 次浏览

据我所知,它们几乎是一样的,除了这里和那里的一些实现细节。Unity 在竞争中的最大优势是它是由微软提供的,有很多公司都害怕 OSS。

一个缺点是,它是相当新的,所以它可能有错误,老玩家已经解决了。

话虽如此,你可能想要 看看这个

我正在为一个用户组准备演示文稿。因此,我刚刚经历了一大堆。即: 自动工厂,MEF,注射,春天。Net,structureMap,Unity,and Windsor.

我想展示一下90% 的情况(构造函数注入,这主要是人们使用 IOC 的原因)。 您可以在这里查看解决方案(VS2008)

因此,两者之间存在一些关键区别:

  • 初始化
  • 目标检索

它们中的每一个都有其他的特性(一些有 AOP,还有更好的小发明,但是通常我想要 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也非常拉巴,总而言之,这是我最喜欢的版本之一。关于结构图如何使用属性的一些非常有趣的想法。

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。网络在太阳底下做一切物联网可以做的事情。但是因为单一化的唯一方法是通过 XML,所以通常通过。网店。虽然有很多。Net/Java 商店使用 Spring。网络,因为它们之间的相似性。网络版的 Spring。Net 和 Java Spring 项目。

注意 : 通过引入 NET CodeConfig,现在可以在代码中进行配置。

温莎

XML 和代码。就像春天。网络,温莎会做任何你想让它做的事情。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 把他最初的答案变成了 博客文章

如果我错了请纠正我,但是我认为 Autofac 本身支持 XML 配置,如下面的链接所示: Autofac XML 配置

Spring 有一个特性,它可以根据参数名称或位置向构造函数或属性注入参数。如果参数或属性是一个简单的类型(例如整数、布尔值) ,这非常有用。参见 这里的例子。我认为这并不能真正弥补 Spring 在代码配置方面的不足。

Windsor 也可以这样做,并且可以在代码不配置的情况下这样做。(如果我错了请纠正我,我只是通过我在这里听到的)。

我想知道联合是否能做到这一点。

需要注意的一点是: Njet 是唯一支持上下文依赖注入的 IoC 容器(根据他们的网站)。但是,因为我没有使用其他 IoC 容器的经验,所以我不能确定这是否成立。

老主题,但是因为这是我输入 Unity vs spring.net 时谷歌给我看的第一个东西..。

如果您不喜欢 XML 配置,Spring 现在可以执行 CodeConfig

Http://www.springframework.net/codeconfig/doc-latest/reference/html/

此外,Spring 不仅仅是一个 DI 容器,如果你看看文档中的“模块”部分,DI 容器是它所做的大量事情的基础。

为了补充我的观点,我已经试过了结构地图和统一。我发现 structureMap 的文档很糟糕/容易误导人,配置起来很麻烦,使用起来也很笨拙。同样,它似乎不支持在解析时重写构造函数参数之类的场景,这对我来说是一个关键的使用点。所以我放弃了它,选择了 Unity,让它在20分钟内做我想做的事情。

我个人使用 Unity,但仅仅是因为它来自微软。我对这个决定感到遗憾,原因只有一个: 它最大的问题是有一个大“ bug”,导致它不断抛出异常。调试时可以忽略异常。但是,如果您运行应用程序 非常喜欢,它会降低应用程序的速度,因为抛出异常是一个昂贵的操作。例如,我目前正在“修复”这个异常在我的代码中的一个地方,在那里 Unity 的异常添加了额外的 4秒到页面的呈现时间。有关更多细节和解决方案,请参见:

是否可以让 Unity 一直不抛出 SynchronizationLockException?