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 ...
随机推荐
- 【spring 注解驱动开发】扩展原理
尚学堂spring 注解驱动开发学习笔记之 - 扩展原理 扩展原理 1.扩展原理-BeanFactoryPostProcessor BeanFactoryPostProcessor * 扩展原理: * ...
- windows编译boost
1. https://www.boost.org 下载boost源码 boost_1_73_0.zip解压. 2.准备编译前的配置,打开vs2017 x86 CMD工具,进入目录boost_1_73_ ...
- HTML基本语法(慕课网学习笔记)
标题 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8& ...
- IDEA 创建Maven Web工程
一.Maven环境搭建 二.Maven常用命令 mvn clean 清除生成的target文件 mvn install 生成target文件 mvn clean install 相当于先删除targe ...
- 常见面试题:java8有什么新特性?
常见面试题:java8有什么新特性? 主要有以下这些新特性: lambda 表达式,经常配合函数式接口使用,可以有效减少代码量 Runnable 是一个函数式接口,下面展示了创建线程三种写法,显然最后 ...
- git所遇到的问题
出现这种情况,或 ERROR: Repository not found. fatal: 无法读取远程仓库. 解决办法如下: 1.先输入$ git remote rm origin(删除关联的orig ...
- 使用ECharts绘制网址径向树状图
an.rustfisher.com有很多内容,很多页面.如果用一个树状图把所有页面展示出来会是什么效果? 第一时间想到了ECharts. 最后效果: https://an.rustfisher.com ...
- centos7 Tomcat 停止服务时报错: java.net.ConnectException: 拒绝连接 (Connection refused)
2021-08-02 1.问题描述 配置完 server.xml 文件后,执行 shutdown.sh 脚本停止服务,出现以下错误 2. 解决方法 查看当前正在运行的 Java 进程号 # 找到 Ja ...
- Jenkins 使用PowerShell插件部署Net5项目
Jenkins安装 PowerShell plugin 插件 新建自由项目 拖到 构建 处,添加 PowerShell 构建 贴入下方脚本即可 # 变量 $ProjectPath = "E: ...
- Android App性能测试之adb命令
本篇文章总结了Android App性能测试过程中常用的adb命令.通过这些adb命令,可以查看App的性能数据,为评判性能好坏作参考. CPU相关 显示占用CPU最大的5个应用 adb shell ...