Autofac 是一款超赞的 .NET IoC 容器 ,在众多性能测评中,它也是表现最优秀的一个。它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改。它的实现方式是将常规的.net类当做 组件 处理。

简单的性能测试

在 LINQPad 中,我们可以很容易的构建出一个测试环境(需要引入 Microsoft.Extensions.DependencyInjection 和 Autofac.Extensions.DependencyInjection 组件):

写一些简单的性能进行测试代码:

在 LINQPad 中对上述代码进行一万次、十万次、百万次三个量级的测试,得出以下报表(纵轴单位为“毫秒”):

从统计图中可以看到,即便是最耗时的 Transient 对象,百万级别创建的时间消耗也不到 400 毫秒。这说明,大多数情况下 Autofac 之类的 IoC 容器不会成为应用的性能瓶颈。

构造函数爆炸

当一个系统不断完善,业务在底层会被不断拆分为小的 Service ,然后在顶层(应用层或表现层)组装以完成功能。这表示在 Controller 中我们需要注入大量的 Service 才能保证功能完备。如果我们需要的对象通过构造函数注入,那么就会造成该构造函数的参数多到爆炸。

nopCommerce 是一个 ASP.NET 开发的电子商城系统,具备商城该有的各种功能和特性。在 ShoppingCartController 中你可以看到以下代码:

构造函数爆炸的性能问题

即便参数再多,在感官上也只是一个强迫症的问题。但构造函数爆炸所造成的影响不仅仅只是看上去没那么舒服而已。当我们注入一个对象时,IoC 容器会保证该对象以及其依赖的对象已经被正确初始化。所以我们不能简单的根据注入对象的数量来判断性能消耗,因为很有可能某个接口的实现依赖了数个其他对象。

当我们访问一个网页时,只会用到 Controller 中的某一个方法,通常,该方法不会对所有注入的对象都产生依赖。这也意味着我们创建了大量非必要的对象,为内存和 GC 造成了压力。

在 ASP.NET Core 中解决构造函数爆炸问题

ASP.NET Core 提供了一个名为 FromServicesAttribute 的属性来帮助解决必须在构造函数中注入依赖的问题。我们可以为 Action 的参数增加此属性,将所需的依赖注入进来:

这当然解决了构造函数爆炸的问题,很好。但同时,该方案也让方法的参数变得复杂也为单元测试留下了障碍,依旧不够完美。

使用 IServiceProvider 解决构造函数爆炸问题

在依赖注入容器中包含的所有对象都可以通过 IServiceProvider 获取到。基于该特性可以实现依赖对象的按需加载功能:

以上代码在 MyService 的构造函数中输出了创建日志。MyController 类型中通过 LazyGetRequiredService 方法实现了 MyService 的按需加载,构造函数也只剩下一个 IServiceProvider 对象。以上代码会产生下面的输出:

可以看到,在调用不依赖 MyService 的方法 NoCallMethod 时,MyService 并没有被创建。直到 CallMethod 被调用后用到了 MyService 时,它才被创建。

向 Volo.Abp 学习

Volo.Abp 在 4.2.0 版本中加入了一个新的接口: IAbpLazyServiceProvider 。

其实现同样采用 IServiceProvider 创建对象,同时使用了字典来保存对实例的引用。如果你和我一样使用 Abp 开发代码,那么 LazyServiceProvider 值得尝试。

.NET 中依赖注入组件 Autofac 的性能漫聊的更多相关文章

  1. 依赖注入组件 Autofac 的小记

    1.  批量给 Service 层自动注入.(支持 ASP.NET Core) builder.RegisterAssemblyTypes(typeof(IProductService).Assemb ...

  2. .NET Core 中依赖注入框架详解 Autofac

    本文将通过演示一个Console应用程序和一个ASP.NET Core Web应用程序来说明依赖注入框架Autofac是如何使用的 Autofac相比.NET Core原生的注入方式提供了强大的功能, ...

  3. 【Unity】微软的一款依赖注入组件

    前言 前面学习了autofac这个依赖注入组件,本来是打算写在一起的,因为这个组件没打算像autofac一样详细的写,只是写下以前自己鼓捣玩搭建框架然后使用的一个依赖注入组件,并且也是进行了封装使用. ...

  4. .Net Core中依赖注入服务使用总结

    一.依赖注入 引入依赖注入的目的是为了解耦和.说白了就是面向接口编程,通过调用接口的方法,而不直接实例化对象去调用.这样做的好处就是如果添加了另一个种实现类,不需要修改之前代码,只需要修改注入的地方将 ...

  5. ASP.NET MVC IOC依赖注入之Autofac系列(二)- WebForm当中应用

    上一章主要介绍了Autofac在MVC当中的具体应用,本章将继续简单的介绍下Autofac在普通的WebForm当中的使用. PS:目前本人还不知道WebForm页面的构造函数要如何注入,以下在Web ...

  6. ASP.NET MVC IOC依赖注入之Autofac系列(一)- MVC当中应用

    话不多说,直入主题看我们的解决方案结构: 分别对上面的工程进行简单的说明: 1.TianYa.DotNetShare.Model:为demo的实体层 2.TianYa.DotNetShare.Repo ...

  7. [Android]使用Dagger 2依赖注入 - 图表创建的性能(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5098943.html 使用Dagger 2依赖注入 - 图表创 ...

  8. 大比速:remoting、WCF(http)、WCF(tcp)、WCF(RESTful)、asp.net core(RESTful) .net core 控制台程序使用依赖注入(Autofac)

    大比速:remoting.WCF(http).WCF(tcp).WCF(RESTful).asp.net core(RESTful) 近来在考虑一个服务选型,dotnet提供了众多的远程服务形式.在只 ...

  9. 使用IDEA详解Spring中依赖注入的类型(上)

    使用IDEA详解Spring中依赖注入的类型(上) 在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(例如属性值)注入Bean组件 ...

随机推荐

  1. PPT技术干货1(下)——数据图表分析、逻辑梳理、高效办公

    数据分析 让数据指导决策,帮你获得业绩增长 数据展示是PPT必备的基础技能, 有些人是简单粗暴的将数据直接堆在页面上: 这样的汇报缺乏重点,不具有针对性. 图表该如何设计呢? 1.数据可视化,内容交互 ...

  2. 简单的xml数据库设计

    我的需求 有时候系统需要存储一些简单的关系型属性,不考虑并发,不考虑性能(一次操作在几ms),数据库没有其他依赖引用,拿过来就可以用 为什么选xml作为数据库? 可读性好 实体的对应关系不严格 , 二 ...

  3. [leetcode]BestTimetoBuyandSellStock买卖股票系列问题

    问题1: If you were only permitted to complete at most one transaction (ie, buy one and sell one share ...

  4. [LeetCode98]98. Validate Binary Search Tree判断二叉搜索树

    判断二叉搜索树的方法是: 中序遍历形成递增序列 //全局变量记录中序遍历产生的序列,因为要递归,所以要用全局变量 List<Integer> list = new ArrayList< ...

  5. 使用pdf.js aspose各种文档转PDF 版本对应license.xml 去水印破解

    在使用pdf.js途中,使用aspose转换的文件一直有水印,在网上找了许多破解办法都是已经失效的,于是乎,就查看了一下jar的源码,找到了版本对应的破解字符(如下):对应版本为 aspose-wor ...

  6. 伯俊BOS2.0关于订金单的处理方案

    订金单功能调整设计 一.     功能确认 BPOS关于订金的使用对应的是"预收单",原"预收单"设置有商品明细,根据客户对订金的需求,取消原有"商品 ...

  7. HelloGitHub 月刊最受欢迎的开源项目 Top10(2020 年)

    作者:HelloGitHub-卤蛋 2020 年已成往事,2021 年悄然而至. 在已经过完的 2020 年里 HelloGitHub 共发布了 12 期月刊,推荐了 419 个开源项目.​每个月的 ...

  8. PHPer 面试

    A:怎么保证促销商品不会超卖? 答:这个问题是我们当时开发时遇到的一个难点,超卖的原因主要是下的订单的数目和我们要促销的商品的数目不一致导致的,每次总是订单的数比我们的促销商品的数目要多,当时我们的小 ...

  9. 首秀:Markdown学习笔记

    # Markdown学习 ## 标题 ### 三级标题 #### 四级标题 ## 字体 **Hello,World!** *Hello,World!* ***Hello,World!*** ~~Hel ...

  10. WEB安全讨论-表单登录是先验证验证码还是密码

    表单登录是先验证验证码还是密码? 肯定是验证码呀!!!这是毋庸置疑的.但是发现有人会验证密码,感觉先验证密码和先验证验证码是一个概念是一样的.但是其实是完全不一样的.下面我们来一起详细的剖析一下: 消 ...