.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中 ...
随机推荐
- 什么是 rabbitmq ?
采用 AMQP 高级消息队列协议的一种消息队列技术,最大的特点就是消费并不需 要确保提供方存在,实现了服务之间的高度解耦
- Spring源码分析笔记--AOP
核心类&方法 BeanDefinition Bean的定义信息,封装bean的基本信息,从中可以获取类名.是否是单例.是否被注入到其他bean中.是否懒加载.bean依赖的bean的名称等. ...
- 微信小程序 MinUI 组件库系列之 price 价格组件
MinUI 是基于微信小程序自定义组件特性开发而成的一套简洁.易用.高效的组件库,适用场景广,覆盖小程序原生框架.小程序组件化框架等,并且提供了高效的命令行工具.MinUI 组件库包含了很多基础的组件 ...
- Android.mk文件如何打日志信息
1. 在mk文件中添加:$(warning "xxx="$(变量名)) 2. 执行lunch,选一个分支,此过程中可以打出添加的log.
- 学习如何运用GitHub网站+出现的问题+Git基本操作总结
首先介绍一下GitHub网站: github是一个基于git的代码托管平台. GitHub 拥有一个非常鼓励合作的社区氛围.这一方面源于 GitHub 的付费模式:私有项目需要付费,而公共项目完全免费 ...
- DOM节点的使用(常用方法+代码)
DOM节点的应用 学习总结 1. 什么是 DOM 2. HTMLDOM 3. 元素获取 元素获取方式 元素节点的属性操作 4. Node 对象的属性和方法 常用属性 常用方法 5. 事件处理 事件驱动 ...
- animate.css使用
解决 使用jquery单纯添加类不能出现动画 使用jQuery向元素中添加类制作动画的时候,需要使用setTimeout实现,因为动画需要从一个状态到另外一个状态!时间设置为0
- Unable to negotiate with xx.xxx.xxxx port 22: no matching host key type found. Their offer: ssh-rsa(解决的两种方式)
异常问题: 下班之前升级了一下Git的版本,结果第二天过来拉取远程最新代码的时候就提示了下面的异常问题: Unable to negotiate with xx.xxx.xxxx port 22: n ...
- IDEA 2022.2.1 Beta 2发布:新增支持Java 18、增强JUnit 5的支持
近日,IDEA 2022.1的Beta 2版本发布了!下面我们一起来看看对于我们Java开发者来说,有哪些重要的更新内容. Java增强 随着Java 18的正式发布,IDEA也在该版本中迅速跟进.目 ...
- 使用 Jenkins 进行持续集成与发布流程图-图解