【问题标题】:Enterprise Library Unity vs Other IoC Containers [closed]企业库 Unity 与其他 IoC 容器 [关闭]
【发布时间】:2023-03-20 02:05:01
【问题描述】:

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

【问题讨论】:

  • 这类问题总是关闭的。意见很重要。有地方放吗?
  • @JesonMartajaya,我想赞扬完全相同的评论,令人讨厌的是问题正在关闭,但没有回复替代方案。

标签: c# .net inversion-of-control unity-container enterprise-library


【解决方案1】:

我正在为一个用户组准备一个演示文稿。因此,我刚刚经历了一堆。即:AutoFac、MEF、Ninject、Spring.Net、StructureMap、Unity、Windsor。

我想展示 90% 的情况(构造函数注入,这主要是人们使用 IOC 的主要目的)。 You can check out the solution here (VS2008)

因此,有几个关键区别:

  • 初始化
  • 对象检索

它们中的每一个都具有其他功能(有些具有 AOP 和更好的 gizmo,但通常我想要 IOC 做的只是为我创建和检索对象)

注意:不同库对象检索之间的差异可以通过使用 CommonServiceLocator 来否定:http://www.codeplex.com/CommonServiceLocator

这给我们留下了初始化,它通过两种方式完成:通过代码或通过 XML 配置 (app.config/web.config/custom.config)。有的两者都支持,有的只支持一个。我应该注意:一些使用属性来帮助 IoC。

以下是我对差异的评估:

Ninject

仅代码初始化(带有属性)。我希望你喜欢 lambdas。初始化代码如下:

 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 如何使用属性的一些非常有趣的想法。

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>();
 });

Unity

初始化代码和 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 CodeConfig

Windsor

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");

Autofac

可以混合使用 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 将他的原始答案变成了blog post

【讨论】:

  • 仅限 XML 配置,使其更难配置。基本上,我看到的唯一想要使用 Spring.Net 的人是以前的 Java 开发人员。
  • Chris,关于您的结论:您能否详细说明 a) 您指的是哪些 C#3 功能,以及 b) 哪种初始化对您很重要?谢谢!
  • 嗨 Nicholas:至于 C# 3 支持,Autofac 已经做的一切。 :) 对于初始化,我希望轻松支持单例/非单例以及每个会话的初始化。最后,我想要通过自定义名称引用的简单方法。 (在 StructureMap 中是 PITA)。我现在比最初写这篇文章时更喜欢的最后一个功能:AutoMocking。我不是一直都用它,但是用着还是很不错的。
  • 您也提到了 MEF,我使用 MEF 来交付我的 IRepository 实现对象并发现它工作得很好。您对 MEF 有何看法?
  • 这是一段 20 分钟的精彩截屏视频,展示了 Unity 的大部分内容:pnpguidance.net/Screencast/…
【解决方案2】:

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

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

话虽如此,您可能想check this out

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

            Can Unity be made to not throw SynchronizationLockException all the time?

            【讨论】:

            • 感谢您的警告!根据this answer from the question you referred to的说法,这个bug现在已经解决了。
            • 为什么 Unity 会抛出异常?通常,异常是“严重错误”(例如无法解决的依赖项),而不是要抑制的东西..
            • 请问,这个“错误”是否已解决或者您是否找到了避免它的方法?我现在在 c#.net 中选择框架,并且很想知道统一是否仍然是时间成本......
            猜你喜欢
            • 2011-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-11-26
            • 2010-10-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多