ASP.NET Core 学习笔记 第二篇 依赖注入
前言
ASP.NET Core 应用在启动过程中会依赖各种组件提供服务,而这些组件会以接口的形式标准化,这些组件这就是我们所说的服务,ASP.NET Core框架建立在一个底层的依赖注入框架之上,它使用容器提供所需的服务。要了解依赖注入容器以及它的机制,我们需要了解什么是依赖注入。
控制反转
说道依赖注入就不得不提控制反转(IoC)。
定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在.NET中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。
好莱坞法则
“不要给我们打电话,我们会给你打电话(don‘t call us, we‘ll call you)”这是著名的好莱坞原则。在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。IIOC的原理就是基于好莱坞原则,所有的组件都是被动的(Passive),所有的组件初始化和调用都由容器负责。
以ASP.NET MVC开发来说,我们只需按照约定的规则(定义好的目录或命名规则)定义对应的controller和View文件即可。整个框架会根据路由规则解析的参数到目标Controller,如果目标Action方法需要呈现一个View,框架会根据约定找到对应的的View文件(.cshtml文件),对其进行动态编译生成html回复给客户端,整个框架都体现了IoC思想。
流程控制
IoC是将流程的控制从应用程序当中迁移到框架当中,框架利用一个引擎驱动整个流程的自动执行。应用程序无须关心工作流程的细节,它只需要启动这个引擎即可。框架会以替丁的形式提供扩展点,应用程序通过注册扩展的方式实现对某个环节的控制。一旦这个引擎(容器)被启动,注册的扩展就会自动参与整个流程的执行。

通过上面这张图不难看出IoC在其中起到的作用。
未使用前: 整个程序相互依赖,当新的需求被提出时,牵一发而动全身,这是我们最不想看到的,在小项目中还能理清关系,当需求越来越多,简直不可想象。
开始使用: 在引入第三方后,各个模块之间没有耦合关系,将依赖降至最低,所有控制都通过IoC集中控制。
使用后: 为了方便观察把中间的IoC容器拿掉后,可以看出各个模块之间已经没有耦合关系,修改单一模块后,再也不需要考虑其他模块。
三种依赖注入方式
1.构造器注入
构造器注入就是在构造函数中借助参数将依赖的对象注入由他创建的对象当中。平时基本都是使用其中的构造函数方式实现注入。
public class A
{
public IB B { get; }
public A(IB b) => B = b;
}
ASP.NET Core 中的使用
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
2.属性注入
通过标注InjectionAttribute特性的方式可以将属性设置为自动注入的依赖属性。
public class A
{
public IB B { get; set; }
[Injection]
public IC C { get; set; }
}
3.方法注入
同样通过标注InjectionAttribute特性的方式可以将该方法标注为注入方法。
public class A
{
public IB B { get; }
[Injection]
public Initialize(IB b) => B = b;
}
除了通过容器初始化服务过程中自动调用实现,我们还可以利用它实现另一种更加自由的方法注入,这种方式在ASP.NET Core中广范应用。在ASP.NET Core启动时会调用Startup对象完成中间件注册,而定义Startup类型时候不需要让他实现某个接口,所以注册Configure方法没有一个固定声明,但可以通过下面方法将任意依赖服务注册到这个方法当中。
public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication1 v1"));
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
生命周期
AddSingleton的生命周期: 项目启动-项目关闭 相当于静态类 只会有一个
AddScoped的生命周期: 请求开始-请求结束 在这次请求中获取的对象都是同一个
AddTransient的生命周期: 请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一个
注意:由于AddScoped对象是在请求的时候创建的,所以不能在AddSingleton对象中使用,甚至也不能在AddTransient对象中使用。
权重: AddSingleton→AddTransient→AddScoped
ASP.Net Core 中自带的注入
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IA, A>;
services.AddSingleton<IB, B>;
services.AddTransient<IC, C>;
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication1", Version = "v1" });
});
}
注意: ASP.Net Core中的注入还是比较简单的,但是当服务变得越来越多时,手动注入就比较麻烦了,后续在介绍其他IoC框架。
ASP.NET Core 学习笔记 第二篇 依赖注入的更多相关文章
- .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式
原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...
- .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]
原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...
- .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]
原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...
- .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC
原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
- .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式
原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...
- ASP.NET Core 学习笔记 第一篇 ASP.NET Core初探
前言 因为工作原因博客断断续续更新,其实在很早以前就有想法做一套关于ASP.NET CORE整体学习度路线,整体来说国内的环境的.NET生态环境还是相对比较严峻的,但是干一行爱一行,还是希望更多人加入 ...
- .NET CORE学习笔记系列(2)——依赖注入[8]: .NET Core DI框架[服务消费]
原文:https://www.cnblogs.com/artech/p/net-core-di-08.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的I ...
随机推荐
- mysql开启远程访问权限的设置
MySql-Server 出于安全方面考虑默认只允许本机(localhost, 127.0.0.1)来连接访问. 所以必须给root修改可以远程访问的权限 1.在连接服务器后,操作mysql系统数据库 ...
- win10下安装mysql5.7-建议安装-自定义位置
所需文件: 文件名字:mysql-installer-community-5.7.13.0.msi 开始安装: 01:勾选: 02:选择下一步 03:选择Custom安装 04:选择下一步 05:选择 ...
- linux centos 设置笔记本合盖不待机
1.设置笔记本合盖不待机 打开配置文件 vi /etc/systemd/logind.conf 将 HandleLidSwitch 变量前的注释 # 去掉 修改 HandleLidSwitch 变量参 ...
- SpringBoot数据访问之整合mybatis注解版
SpringBoot数据访问之整合mybatis注解版 mybatis注解版: 贴心链接:Github 在网页下方,找到快速开始文档 上述链接方便读者查找. 通过快速开始文档,搭建环境: 创建数据库: ...
- java的stream的使用
过滤 filter: //匹配第一个元素 Optional<Integer> findFirst=list.stream().filter(x->x>6).findFirst( ...
- centos7 netstat
netstat 是控制台命令,它可以显示路由表.实际的网络连接以及每一个网络接口设备的状态信息.Netstat 用于显示与 IP . TCP . UDP 和 ICMP 协议相关的统计数据,一般用于检验 ...
- AWS扩容EC2实例根空间
文章原文 aws 端操作 先在EC2 实例中选中磁盘 然后打开跟设备 修改大小后保存 ec2 端操作 lsblk 查看当前设备的磁盘编号 df -T -H 查看扩容前的空间大小并确定磁盘格式 grow ...
- NOIP模拟22「d·e·f」
T1:d 枚举. 现在都不敢随便打枚举了. 实际上我们只关注最后留下的矩阵中最小的长与宽即可. 所以我们将所有矩阵按a的降序排列. 从第\(n-m\)个开始枚举. 因为你最多拿 ...
- 随机生成uuid序号
function guid() { function S4() { return (((1+Math.random())*0x10000)|0).toString(16).substring(1); ...
- mysql多次连接后会产生最大失败值
解决办法 可以更改max_connection_errors的值,即提高允许的max_connection_errors的数量 1.进入mysql 1)首先查看该属性设置为多大:命令:show glo ...