asp.net core 系列 3 依赖注入服务
一. 依赖注入概述
在软件设计的通用原则中,SOLID是非常流行的缩略语,它由5个设计原则的首字母构成:单一原则(S)、开放封闭原则(O)、里氏替换原则(L)、接口分离原则(I)、依赖反转原则(D)。本篇介绍依赖反转原则以及在ASP.NET Core中的实现。
直接依赖是指:当一个类需要另一个类协作来完成工作的时候就产生了依赖。举例比如:模块 A 调用模块 B 中的函数,而模块 B 又调用模块 C 中的函数,则编译时 A 取决于 B,而 B 又取决于 C。这是有严重的依赖关系,不属于松散耦合。
依赖反转是指:高层模块不应该依赖低层模块,二者都应该依赖于抽象,是对接口而不是实现编程。当一个类(Class)需要被外部依赖,就需要把它抽象成一个接口(interface),如何把这个接口变成具体可调用的实例,就是由依赖注入来完成。依赖反转是生成松散耦合应用程序的关键一环。当应用依赖反转原则后,A 可以调用 B 实现的抽象上的方法,让 A 可以在运行时调用 B,而 B 又在编译时依赖于 A 控制的接口。 运行时程序执行的流程保持不变,但接口引入意味着可以轻松插入这些接口的不同实现。
假设一个方法从流读取字节,并把它们写入某个缓冲:
//直接依赖 这里的伪代码依赖于两个低层模块,读取器和写入器。
void Copy()
{
Byte byte1;
Reader reader = new Reader();
Writer writer = new Writer();
while (byte1 = reader.ReadFromStream())
writer.WriteTobuffer(byte1);
}
//依赖反转 这里的伪代码依赖于两个抽象类,读取器和写入器。
void Copy(IReader reader, IWriter writer)
{
Byte byte1;
while (byte1 = reader.ReadFromStream())
writer.WriteTobuffer(byte1)
}
上面接口的读取器和写入器的实例谁来提供呢?需要使用依赖注入模式。实现依赖注入需要使用IoC 容器,目前有Unity和MEF 2 二种IoC 容器工具来实现。以及下面讲到ASP.NET Core自带的依赖注入实现。
二. ASP.NET Core依赖注入
ASP.NET Core 支持依赖关系注入的设计模式,是类及其依赖关系之间实现控制反转 (IoC)的技术。在ASP.NET Core中依赖注入解决的问题包括:
(1) 使用接口抽象化依赖关系实现。
(2) 注册服务容器中的依赖关系。ASP.NET Core内置的服务容器 IServiceProvider。 实现在Startup.ConfigureServices 方法中注册服务(服务一般是接口)。
(3) 将服务注入到使用它的类的构造函数中。
下面示例中,使用具体类型 MyDependency 注册 IMyDependency 服务, 注册将服务生存期的范围限定为单个请求的生存期。在MyDependency实现类中使用框架内部已注入好的ILogger来帮助打印日志输出。
// 第一步 使用接口抽象化来实现依赖反转, 定义 IMyDependency 服务
public interface IMyDependency
{
Task WriteMessage(string message);
}
// IMyDependency 服务的实现类
public class MyDependency : IMyDependency
{
private readonly ILogger<MyDependency> _logger; public MyDependency(ILogger<MyDependency> logger)
{
_logger = logger;
} public Task WriteMessage(string message)
{
_logger.LogInformation(
"MyDependency.WriteMessage called. Message: {MESSAGE}",
message);
return Task.FromResult();
}
}
// 第二步在 将IMyDependency服务注册到服务容器中。
public void ConfigureServices(IServiceCollection services)
{
//....
//每次请求时创建,贯穿整个请求
services.AddScoped<IMyDependency, MyDependency>();
//....
}
// 第三步 将服务注入到使用它的类的构造函数中,在Index.cshtml.cs类中调用IMyDependency服务的WriteMessage方法
public class IndexModel : PageModel
{
private readonly IMyDependency _myDependency; public IndexModel(IMyDependency myDependency)
{
this._myDependency = myDependency;
} public void OnGet()
{
_myDependency.WriteMessage("IndexModel.OnGetAsync created this message."); }
}
下面是输出WriteMessage方法的日志信息:

参考文献:
Microsoft.NET 企业级应用 架构设计
官方文档:ASP.NET Core 依赖注入
asp.net core 系列 3 依赖注入服务的更多相关文章
- ASP.NET Core系列:依赖注入
1. 控制反转(IoC) 控制反转(Inversion of Control,IoC),是面向对象编程中的一种设计原则,用来降低代码之间的耦合度. 1.1 依赖倒置 依赖原则: (1)高层次的模块不应 ...
- ASP.NET Core中的依赖注入(3): 服务的注册与提供
在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...
- ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...
- ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】
本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们已经可以正确是使用这些与依赖注入相关的API了.如果你还 ...
- 拥抱.NET Core系列:依赖注入(2)
上一篇"拥抱.NET Core系列:依赖注入(1)"大体介绍了服务注册.获取和生命周期,这一篇来做一些补充. 由于内容跨度大(.NET Core.ASP.NET Core),所以文 ...
- ASP.NET Core 中的 依赖注入介绍
ASP.NET Core 依赖注入 HomeController public class HomeController : Controller { private IStudentReposito ...
- ASP.NET Core中的依赖注入(2):依赖注入(DI)
IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...
- ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】
通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的.ServiceProvider最 ...
随机推荐
- pycharm的list中clear的应用
#清空的意思 li = [11,22,33,44] li.clear() print(li) #输出[],就是把列表清空
- spring 应用
Spring框架本身会托管bean. 1.使用时需要注意对于包本身扫描配置. 2.使用注解本身包需要在扫描路径下.
- MachineLearningOnCoursera
Week Six F Score \[\begin{aligned} P &= &\dfrac{2}{\dfrac{1}{P}+\dfrac{1}{R}}\\ &= & ...
- APM(pixhawk)飞控疑难杂症解决方法汇总(持续更新)
本文转自下面博主 https://blog.csdn.net/junzixing/article/details/79310159 APM/Pixhawk常用链接汇总(持续更新) https://bl ...
- [CSAcademy]Find the Tree
[CSAcademy]Find the Tree 题目大意: 交互题. 有一棵\(n(n\le2000)\)个结点的树,但是你并不知道树的形态.你可以调用\({\rm query}(x,y,z)\)( ...
- MyBatis3系列__06查询的几点补充
关于查询的一点补充: 当查询部门信息时,希望查询该部门下的所有员工,下面会采取两种方式实现: 1.联合查询 public Department getDeptWithEmpById(Integer i ...
- SPFA板子 (背景:Luogu P3371 单源最短路径)
Luogu P3371 单源最短路径 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数 ...
- webpack-dev-server和webpack-dev-middleware的区别
webpack-dev-server webpack-dev-server实际上相当于启用了一个express的Http服务器+调用webpack-dev-middleware.它的作用主要是用来伺服 ...
- dedecms 后台可以上传mp4,但无法选择
原文链接 找到 /include/dialog/select_media.php 找到rmvb,在其后面加 “|mp4” 即可. 1
- [Codeforces Round #516][Codeforces 1063B/1064D. Labyrinth]
题目链接:1063B - Labyrinth/1064D - Labyrinth 题目大意:给定一个\(n\times m\)的图,有若干个点不能走,上下走无限制,向左和向右走的次数分别被限制为\(x ...