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. Kafka Eagle 管理平台

    Kafka-Eagle简介 源代码地址:https://github.com/smartloli/kafka-eagle Kafka Eagle是什么 Kafka Eagle是一款用于监控和管理Apa ...

  2. npm国内淘宝镜像

    理由 由于npm的registry地址是国外的,速度很慢,所以推荐使用淘宝镜像:https://registry.npm.taobao.org 配置方法 临时配置 npm --registry htt ...

  3. JAVA读取EXCEL_自动生成实体类

    代码实现PropertyAnno.java import java.lang.annotation.ElementType; import java.lang.annotation.Retention ...

  4. 01 . Go之从零实现Web框架(类似Gin)

    设计一个框架 大部分时候,我们需要实现一个 Web 应用,第一反应是应该使用哪个框架.不同的框架设计理念和提供的功能有很大的差别.比如 Python 语言的 django和flask,前者大而全,后者 ...

  5. Linux内核源码分析之setup_arch (三)

    1. 前言 在 Linux内核源码分析之setup_arch (二) 中介绍了当前启动阶段的内存分配函数memblock_alloc,该内存分配函数在本篇将要介绍paging_init中用于页表和内存 ...

  6. python-scrapy爬取某招聘网站信息(一)

    首先准备python3+scrapy+mysql+pycharm... 这次我们选择爬取智联招聘网站的企业招聘信息,首先我们有针对的查看网站的html源码,发现其使用的是js异步加载的方式,直接从服务 ...

  7. “开源、共享、创新” 2020 中国.NET开发者大会小结

    大会的新闻稿在2020年12月31日正式发布:开源·共享·创新|2020年中国.NET开发者大会圆满收官! , 本文是这篇新闻的补充性文章,仅代表个人对大会的各方面分享内容的一个小结. 在2019年上 ...

  8. 【转载】VUE的背景图引入

    我现在的项目要将登录页面的背景引一图片做为背景图片,按原jsp中的写法,发现无法找到背景图片,最后从网上查资料,采用上面的写法,成功显示出背景图片,参考网址 https://blog.csdn.net ...

  9. MySql Docker 主主配置

    MySql 主主 准备2台Linux服务器,并且在两台服务器上,同时安装docker,国内的同学可以使用aliyun的镜像安装. curl -fsSL https://get.docker.com - ...

  10. 整合.NET WebAPI和 Vuejs——在.NET单体应用中使用 Vuejs 和 ElementUI

    .NET简介 .NET 是一种用于构建多种应用的免费开源开发平台,例如: Web 应用.Web API 和微服务 云中的无服务器函数 云原生应用 移动应用 桌面应用 1). Windows WPF 2 ...