.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中 ...
随机推荐
- Spring-boot-菜鸟-快速创建应用
file-new-project 选择Spring boot ,然后选择自己的配置类型,maven jdk版本等 结果: 目录解析: resources文件夹中目录结构 static:保存所有的静态 ...
- 什么是 bean 装配?
装配,或 bean 装配是指在 Spring 容器中把 bean 组装到一起,前提是容器需要 知道 bean 的依赖关系,如何通过依赖注入来把它们装配到一起.
- 小米手机BL解锁连接不上手机
解锁工具下载页面:http://www.miui.com/unlock/download.html 线刷工具下载页面:http://www.miui.com/shuaji-393.html 额外注意说 ...
- Java 中应该使用什么数据类型来代表价格?
如果不是特别关心内存和性能的话,使用 BigDecimal,否则使用预定义精度的 double 类型.
- 学习Apache(四)
介绍 Apache HTTP 服务器被设计为一个功能强大,并且灵活的 web 服务器, 可以在很多平台与环境中工作.不同平台和不同的环境往往需要不同 的特性,或可能以不同的方式实现相同的特性最有效率. ...
- 学习saltstack (三)
salt是一个新的基础平台管理工具,2011-02-20诞生,创造者Thoms SHatch,起名salt原因生活中常见.易记,使用saltstack.com原因这个域名没有被注册,Because s ...
- leetcode_两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同 ...
- hackgame2018_签到
hackgame2018_签到 进入题目得到如下提示 尝试提交 发现这个输入框长度做了限制我们将前端js修改一下 然后提交以下这样就发现了flag这题比较简单--
- 走一步再走一步,揭开co的神秘面纱
前言 原文地址 源码地址 了解co的前提是已经知晓generator是什么,可以看软大神的Generator 函数的语法,co是TJ大神写的能够使generator自动执行的函数库,而我们熟知的koa ...
- 小程序web开发框架-weweb介绍
weweb是一个兼容小程序语法的前端框架,你可以用小程序的写法,来写web单面应用.如果你已经有小程序了,通过它你可以将你的小程序运行在浏览器中.在小程序大行其道的今天,它可以让你的小程序代码得到最大 ...