.Net Core 依赖注入(IOC) 一些简单的使用技巧
原文链接:https://www.cnblogs.com/ysmc/p/16240534.html
.Net Core 在使用IOC后,我们不必再浪费精力在管理实例的生命周期上,交给IOC代替我们管理,减少我们成吨的代码,面向接口编程更是灵活到了极致,而IOC的三种生命周期应该怎么去使用呢,Transient(瞬态)、Scoped(作用域)、Singleton(单例)。
Transient(瞬态)
这个没什么好说的,就是每次注入的时候,容器自动 new 一个实例,用完就丢;
Scoped(作用域)
以Web来说,作用域的生命周期就是当次请求,请求开始后的第一次注入,就是它生命的开始,直到请求结束;
我个人常用来减少数据获取,提升请求响应,举一个例子:A服务是获取全国地级市信息的,以作用域的方式注册到IOC容器中,B、C、D 都注入了A服务并使用了它;一个业务接口,刚好涉及到了B、C、D,当接口被调用,代码执行到了B,第一次调用了 A 服务请求数据库获取了全国地级市数据;然后执行到了C,又一次使用了A服务获取了数据,最后D;一个请求下来,A被使用了3次,获取了3个同样的数据结果,这完全是在浪费资源;
1 public class AService
2 {
3 public async CityData GetCityDataAsync()
4 {
5 return await GetDatasFromApi();
6 }
7 }
8
9 public class BService
10 {
11 private readonly AService _aService;
12
13 public BService(AService aService)
14 {
15 _aService = aService;
16 }
17
18 public async Task Execute()
19 {
20 await _aService.GetCityDataAsync();
21 }
22 }
23
24 public class CService
25 {
26 private readonly AService _aService;
27
28 public CService(AService aService)
29 {
30 _aService = aService;
31 }
32
33 public async Task Execute()
34 {
35 await _aService.GetCityDataAsync();
36 }
37 }
38
39 public class DService
40 {
41 private readonly AService _aService;
42
43 public DService(AService aService)
44 {
45 _aService = aService;
46 }
47
48 public async Task Execute()
49 {
50 await _aService.GetCityDataAsync();
51 }
52 }
那我们应该怎么做呢,首先我们回顾一下 Scoped 的生命周期,可以说是一个实例,贯穿了整一个请求,那我们是不是可以定义一个变量,请求数据前先判断这个变量有没有值,没有就去获取数据,给它赋值,下次再调用的时候,直接返回这个变量的数据,这样不管这个服务被调用多少次,它也只是调用了一次数据库,大大节省了资源。
1 public class AService
2 {
3 private List<CityData> cityDatas;
4
5 public async List<CityData> GetCityDataAsync()
6 {
7 if(cityDatas == null|| !cityDatas.Any())
8 {
9 cityDatas = await GetDatasFromApi();
10 }
11
12 return cityDatas;
13 }
14 }
有人可能说会说了,不就是多调用几次数据库,现在服务器的性能这么好,不在乎这一点的资源;确实,如果只是多调用几次数据库,对于一些小系统来说,跟挠痒痒一样,那这里的调用数据库换成调用 WebApi 呢?如果还是调用第三方的 API 呢?一次Http请求,不往大的说,从请求到获取到数据,花个100ms很正常吧(网络非常好的情况当我没说),那这个接口不需要多,调用10次就1s了,还没算上其它业务逻辑的耗时呢,如果还需要调用其它的api,那响应时间就更长咯,难道你让用户打开一个页面,或者点击一个按钮,需要等上两三秒才有响应吗,这样的用户体验就非常糟糕了。
Singleton(单例)
来自依赖关系注入容器的服务实现的每一个后续请求都使用同一个实例。 如果应用需要单一实例行为,则允许服务容器管理服务的生存期。必须是线程安全的,并且通常在无状态服务中使用。
在单例中,不要直接注入作用域的服务,这会引起很多莫名其妙的错误,一定要使用的话,就自己创建,自己管理它的生命周期:
public class Scope
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public Scope(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
} public async Task CreateScope()
{
using var scope = _serviceScopeFactory.CreateScope(); var service = scope.ServiceProvider.GetRequiredService<IService>();
}
}
ActivatorUtilities
有些情况下,例如当你不想把使用次数极低的类注册到容器中,或者这个类的构造函数需要传入一些参数,但是又需要用到容器中的服务的时候,你可以使用 ActivatorUtilities 中的 CreateInstance 去创建它,它会自动给构造函数注入所需的服务,并且还可以给构造函数传参,满足上面所说情况的需求。
1 public class TestTask : ITask
2 {
3 private readonly IServiceScopeFactory _serviceScopeFactory;
4
5 private readonly IRabbitMQService _rabbitMQService;
6
7 private readonly string _name;
8
9 public TestTask(IServiceScopeFactory serviceScopeFactory, IRabbitMQService rabbitMQService, string name)
10 {
11 _serviceScopeFactory = serviceScopeFactory;
12 _rabbitMQService = rabbitMQService;
13 _name = name;
14 }
15
16 /// <summary>
17 ///
18 /// </summary>
19 /// <param name="cancellationToken"></param>
20 /// <returns></returns>
21 /// <exception cref="NotImplementedException"></exception>
22 public async Task Execute(CancellationToken cancellationToken)
23 {
24 try
25 {
26 using var scope = _serviceScopeFactory.CreateScope();
27
28 var executionService = scope.ServiceProvider.GetService<ITaskExecutionService>();
29
30 if (executionService != null)
31 {
32 await _rabbitMQService.RabbitMQReceiveService.SingleAsync(executionService.ExecuteAsync);
33 }
34 }
35 catch (Exception err)
36 {
37
38 Console.WriteLine(err.Message);
39 }
40 }
41 }
使用 ActivatorUtilities 创建:
1 var testTask = ActivatorUtilities.CreateInstance<TestTask>(serviceProvider, "test");
2
3 await testTask.Execute(new CancellationToken());
写在最后
Bootstrap Blazor 官网地址:https://www.blazor.zone
希望大佬们看到这篇文章,能给项目点个star支持下,感谢各位!
star流程:
1、访问点击项目链接:BootstrapBlazor
2、点击star,如下图,即可完成star,关注项目不迷路:

另外还有两个GVP项目,大佬们方便的话也点下star呗,非常感谢:
BootstrapAdmin 项目地址:
https://gitee.com/LongbowEnterprise/BootstrapAdmin
SliderCaptcha 项目地址:
https://gitee.com/LongbowEnterprise/SliderCaptcha
交流群(QQ)欢迎加群讨论
BA & Blazor ①(795206915) BA & Blazor ②(675147445)


.Net Core 依赖注入(IOC) 一些简单的使用技巧的更多相关文章
- .net core 依赖注入, autofac 简单使用
综述 ASP.NET Core 支持依赖注入, 也推荐使用依赖注入. 主要作用是用来降低代码之间的耦合度. 什么是控制反转? 控制反转(Inversion of Control,缩写为IoC),是面 ...
- # ASP.NET Core依赖注入解读&使用Autofac替代实现
标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...
- NET Core依赖注入解读&使用Autofac替代实现
NET Core依赖注入解读&使用Autofac替代实现 标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之九 || 依赖注入IoC学习 + AOP界面编程初探
更新 1.如果看不懂本文,或者比较困难,先别着急问问题,我单写了一个关于依赖注入的小Demo,可以下载看看,多思考思考注入的原理: https://github.com/anjoy8/BlogArti ...
- ASP.NET Core依赖注入最佳实践,提示&技巧
分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...
- ASP.NET Core依赖注入解读&使用Autofac替代实现【转载】
ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Autofac实现和自定义实现扩展方法 3.1 安装Autof ...
- Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor
Webservice WCF WebApi 注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...
- Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之九 || 依赖注入IoC学习 + AOP界面编程初探
本文梯子 本文3.0版本文章 更新 代码已上传Github+Gitee,文末有地址 零.今天完成的绿色部分 一.依赖注入的理解和思考 二.常见的IoC框架有哪些 1.Autofac+原生 2.三种注入 ...
- net core 依赖注入问题
net core 依赖注入问题 最近.net core可以跨平台了,这是一个伟大的事情,为了可以赶上两年以后的跨平台部署大潮,我也加入到了学习之列.今天研究的是依赖注入,但是我发现一个问题,困扰我很久 ...
- [译]ASP.NET Core依赖注入深入讨论
原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...
随机推荐
- elasticsearch 的倒排索引是什么 ?
解答:通俗解释一下就可以. 传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置. 而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表 即为倒排索引. 有了倒排索引,就能实现 ...
- 学习Kvm(二)
一.走进云计算 云计算:云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问, 进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务),这些资源能够被快速提供, ...
- 时间工具类之“ JDK1.8中 LocalDate、LocalTime、LocalDateTime、LocalDateTimeUtil四个时间工具类”
一.使用的原因 在JDK8发布的时候,推出了LocalDate.LocalTime.LocalDateTime这个三个时间处理类,以此来弥补之前的日期时间类的不足,简化日期时间的操作. 在Java8之 ...
- docker 容器简单使用
文章目录 docker简介 docker容器简单使用 1.HelloWorld 2.运行交互式的容器 3.启动容器(后台模式) 安装docker容器的博文有很多这里就不做过多赘述了,另外如果不想安装d ...
- USART_GetITStatus()和USART_GetFlagStatus()的区别
USART_GetITStatus()和USART_GetFlagStatus()的区别 都是访问串口的SR状态寄存器,唯一不同是,USART_GetITStatus()会判断中断是否开启,如果没开启 ...
- C 语言中 include <> 与include "" 的区别?
#include < > 引用的是编译器的类库路径里面的头文件. #include " " 引用的是你程序目录的相对路径中的头文件,如果在程序目录没有找到引用的头文件则 ...
- jq点击改变元素样式、添加类,显示隐藏,图标旋转,再次点击还原;表格点击显示下拉详情
点击前 点击后 <tr> <td class="right" data-id="{$vo.id}" id="{$vo.id}&quo ...
- React+Webpack+ES6 兼容低版本浏览器(IE9)解决方案
虽然过了兼容IE6的噩梦时代,IE依旧阴魂不散,因为你可能还要兼容IE9.在ES6已经普及的今天,用ES6写react已经成了标配.但是babel编译的js语法,由于某些不规范的写法,可能在IE9下不 ...
- 推荐一款强大的轻量级模块化WEB前端快速开发框架--UIkit
前言 今天给大家分享一款强大的轻量级模块化WEB前端快速开发框架--UIkit 到目前(2016-06-20)为止,UIkit在github上的Forks已达到了1350个,而Stars更是达到了69 ...
- 纯css模拟电子钟
先看效果 演示地址: https://yueminhu.github.io/di...点击左边拉环切换夜间模式. 用到了伪元素生成数字的小三角`currentColor和color: inherit` ...