我应该使用哪个依赖注入工具? [关闭]

Posted

技术标签:

【中文标题】我应该使用哪个依赖注入工具? [关闭]【英文标题】:Which Dependency Injection Tool Should I Use? [closed] 【发布时间】:2010-09-14 00:23:59 【问题描述】:

我正在考虑在我们的用户界面中使用 Microsoft Unity 作为我的依赖注入工具。

我们的中间层已经在使用 Castle Windsor,但我认为我应该坚持使用 Microsoft。

有人对最好的依赖注入工具有什么想法吗?

Autofac Castle MicroKernel/Windsor PicoContainer.NET Puzzle.NFactory Spring.NET StructureMap Ninject Unity Simple Injector NauckIT.MicroKernel WINTER4NET ObjectBuilder

【问题讨论】:

相关问题***.com/questions/2216684/… ObjectBuilder 不是 DI 框架。它是用于构建 DI 框架的框架。 【参考方案1】:

最近使用了其中的 6 个(Windsor、Unity、Spring.Net、Autofac、Ninject、StructureMap)我可以快速总结每一个,我们的选择标准和我们最终的选择。

注意:我们没有将 PicoContainer.Net 视为我们的团队之一,他们认为 .Net 端口与 Java 版本相比相当差。我们也没有关注 ObjectBuilder,因为 Unity 是在 ObjectBuilder2 之上构建的,默认情况下被认为是更好的选择。

首先,我可以说它们或多或少都非常相似,这实际上归结为最适合您的方法以及您的具体要求。我们的要求包括:

要求

基于构造函数的注入(我们打算使用属性、字段或方法注入) 可编程配置( XML) 容器层次结构(每个应用程序、每个请求和每个会话一个,以更隐式地将组件生命周期范围绑定到容器) 组件生命周期管理(用于更精细的范围界定,例如瞬态/单例) 从接口注入到类型或具体实例(例如ILogger -> typeof(FileLogger)ILogger -> new FileLogger()) 高级组件创建/用于预/后初始化的“创建事件机制” 正确处理IDisposable容器拆解组件

有据可查和/或在线信息随时可用

注意:虽然性能是一项要求,但在选择时并未将其考虑在内,因为根据benchmark

看来,所有审查过的容器都相似

测试

每个容器都用于一个典型的 Asp.Net webforms 项目(因为这是我们的目标应用程序类型)。我们使用带有单个简单用户控件的单个简单页面,每个控件分别继承自一个基本页面/基本控件。我们在BasePage 上使用 1 个容器作为“per request”范围容器,在 global.asax 上使用 1 个容器作为“应用程序”范围,并尝试将它们链接在一起,以便可以从两个容器中解决依赖关系。

每个 Web 应用程序共享一组人为的域对象,模拟多层次的依赖关系、范围类型(​​单例/瞬态)以及托管和非托管类(需要IDisposable)。 “***”依赖组件是从 BasePage 上的方法手动注入的。

结果

Windsor - 满足所有标准并拥有良好的案例历史、博客社区和在线文档。易于使用,可能是事实上的选择。通过工厂设施创建高级组件。还允许链接单独创建的容器。

Spring.Net - 冗长且无用的文档以及不明显/易于可编程配置。不支持泛型。未选择

Ninject - 易于使用,文档清晰。强大的功能集可以满足我们的所有要求,但容器层次结构除外,因此很遗憾没有被选中。

StructureMap - 文档很少,虽然有一个非常高级的功能集可以满足我们的所有要求,但是没有用于容器层次结构的内置机制,尽管可以使用 for 循环一起破解参见 here lambda 表达式流式接口起初看起来确实有点过于复杂,但可以封装起来。

Unity - 有据可查、易于使用并符合我们所有的选择标准,并且有一个简单的扩展机制来添加我们需要的创建前/后创建事件机制。必须从父容器创建子容器。

Autofac - 有据可查且相对易于使用,虽然 lambda 表达式配置看起来确实有点过于复杂,但同样可以轻松封装。组件范围是通过“标记”机制实现的,并且所有组件都使用构建器预先配置,这有点不方便。子容器是从父容器创建的,并从“标签”分配组件。允许泛型注入。

结论

我们最终的选择是在 Windsor 和 Unity 之间,而这一次我们选择了 Unity,因为它易于使用、文档、扩展系统以及处于“生产”状态。

【讨论】:

漂亮而聪明的推理。 有趣的是看到接受的答案说远离 Unity,而投票最多的答案选择 Unity! 是的,我也觉得这很有趣。我们对所有容器进行了同等测量,并忽略了反 MS 偏差。然而,每种情况都不同,应该选择当时适合他们的解决方案。碰巧我们结束了重新发明***并编写了自己的***,我们将很快开源 blatent 插件,但在我的研究之后,我为 .Net 创建了一个轻量级容器。我相信它是目前业内最快的,并且在 IoC 中封装了我最需要的东西。警告购买者:正在进行中code.google.com/p/yadic 这个答案发生了什么?最后一部分好像不见了……【参考方案2】:

如果您的系统在设计时考虑了 IoC/DI,那么坚持使用一个容器并不是很重要。通过正确的方法,您可以轻松地更改 IoC 库。

当然,容器必须提供足够的灵活性来支持常见的广泛使用的场景(生命周期管理、适当的容器嵌套、XML 和代码配置、拦截、快速解析)。

我建议在 Castle(广泛使用并且有很多集成库)和 Autofac(轻量级、快速并且具有适当的容器嵌套,但没有那么广泛使用)之间进行选择

Hanselman 有一个comprehensive list of IoC containers

PS:你不想使用 Unity

【讨论】:

您能否详细说明 Unity 备注?为什么这是一个糟糕的选择? 在 Windsor 之前使用 ent lib 之后 - 我对 MS 的任何尝试创建诸如“策略注入器”之类的任何东西都有非常消极和过敏的反应!除了 asp.net mvc :) 这不是说服的好方法,只是告诉不要使用没有任何 cmets 或信息的东西(10 年后评论:))。【参考方案3】:

这是一篇比较 .NET IoC 容器的好文章。 http://blog.ashmind.com/index.php/2008/08/19/comparing-net-di-ioc-frameworks-part-1/

【讨论】:

哇,那篇文章的细节量惊人。完全值得一读。它还有第 2 部分:blog.ashmind.com/index.php/2008/09/08/…【参考方案4】:

我一年前开始使用Autofac,从那以后就再也没有回头。

【讨论】:

【参考方案5】:

我是 Autofac 的粉丝,但 Windsor 和 Unity 都会做得很好(尽管 Windsor 比 Unity 更有能力,并且不需要归因于您的代码)。不过,在系统中坚持使用单个容器有很多很好的非技术原因。

【讨论】:

是什么让您说(暗示)Unity 要求您为代码添加属性?我正在使用它,并且根本不需要归因我的代码。【参考方案6】:

使用有效的方法。大多数都具有他们独有的功能,并且几乎所有功能都比 Unity 更丰富。如果你只需要统一,你当然可以使用它。

仅仅因为它来自 Microsoft 而使用 Microsoft 的统一性是一种糟糕的决策方式。考虑一下您需要什么以及为什么,然后选择适合您需要的那个。

但是,如果可能的话,我赞同坚持使用单个容器的概念。

【讨论】:

【参考方案7】:

我一直在使用Managed Extensibility Framework,发现它很容易使用。一直是integrated into .NET 4。

【讨论】:

MEF 不是 IoC 容器:***.com/questions/42251/… @Mauricio Scheffer:MEF 使用依赖注入模式来解决人们在开始考虑将 IOC/DI 框架引入项目时面临的许多架构问题。 OP 没有提供任何迹象表明他的需求超出了 MEF 擅长的范围,在这种情况下,它可能是一个简单、可行且极其轻量级的选择。【参考方案8】:

除非您已经对某个可能的 IoC 容器解决方案所使用的特定子技术有经验和个人偏好,否则它们都运行良好,而且我看不到任何一个具有“杀手级功能”的人它从其他人中脱颖而出。 Unity 可能最适合已经使用 P&P Enterprise Library 4.x 的解决方案...

【讨论】:

【参考方案9】:

IoC Container Benchmark - Performance comparison 有 20 多种产品的性能和特性比较表,并保持最新状态。

文章的结论:

SimpleInjector、Hiro、Funq、Munq 和 Dynamo 提供了最好的 性能,它们非常快。试试看!

尤其是Simple Injector 似乎是个不错的选择。速度很快,很好 文档,还支持拦截等高级场景 和通用装饰器。

【讨论】:

以上是关于我应该使用哪个依赖注入工具? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

依赖注入和使用接口?

依赖注入是一种设计模式吗? [关闭]

当您还需要“默认”具体依赖项时,哪个是更好的依赖注入模式?

Flutter - 使用依赖注入时何时关闭流

当 API 关闭时,Xamarin 表单依赖注入 HttpClient 超时不起作用

ASP.Net Core 使用啥依赖注入框架?