136

与其他 IoC 容器(Windsor、Spring.Net、Autofac ..)相比,使用 Enterprise Library Unity 的优缺点是什么?

4

8 回答 8

237

我正在为一个用户组准备一个演示文稿。因此,我刚刚经历了一堆。即: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 将他的原始答案变成了一篇博文

于 2009-01-08T03:35:11.270 回答
7

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

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

话虽如此,您可能想检查一下

于 2009-01-04T21:27:16.553 回答
4

旧线程,但因为这是谷歌在我输入 unity vs spring.net 时向我展示的第一件事......

如果你不喜欢 XML 配置,Spring 现在会做 CodeConfig

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

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

于 2011-09-28T09:28:13.287 回答
3

如果我弄错了,请纠正我,但我认为 Autofac 本身支持此链接中列出的 XML 配置:Autofac XML 配置

于 2009-02-16T04:08:03.190 回答
2

Spring 有一个特性,它可以根据参数名称或位置向构造函数或属性注入参数。如果参数或属性是简单类型(例如整数、布尔值),这将非常有用。请参阅此处的示例。我认为这并不能真正弥补 Spring 无法在代码中进行配置的原因。

Windsor 也可以做到这一点,并且可以在代码而不是配置中做到这一点。(如果我错了,请纠正我,我只是通过我在这里听到的内容)。

我想知道Unity是否可以做到这一点。

于 2009-11-27T11:34:12.637 回答
2

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

于 2010-11-12T00:37:00.237 回答
1

只是为了增加我的 2 美分,我尝试了 StructureMap 和 Unity。我发现 StructureMap 的文档记录很差/有误导性,配置起来很麻烦,而且使用起来很笨拙。同样,它似乎不支持解析时构造函数参数覆盖之类的场景,这对我来说是一个关键的使用点。所以我放弃了它并选择了 Unity,它在大约 20 分钟内完成了我想做的事情。

于 2012-04-24T19:37:49.887 回答
1

我个人使用 Unity,但只是因为它来自 Microsoft。我对这个决定感到遗憾有一个原因:它最大的问题是有一个大“错误”导致它不断抛出异常。您可以在调试时忽略异常。但是,如果您遇到它,它会极大地减慢您的应用程序,因为抛出异常是一项昂贵的操作。例如,我目前正在我的代码中的一个地方“修复”这个异常,Unity 的异常使页面的渲染时间增加了4 秒。有关更多详细信息和解决方法,请参阅:

可以让 Unity 始终不抛出 SynchronizationLockException 吗?

于 2012-05-31T13:00:14.043 回答