依赖项是指另一个对象所依赖的对象。 使用其他类所依赖的 WriteMessage 方法检查以下 MyDependency 类:

 
public class MyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}");
}
}

类可以创建 MyDependency 类的实例,以便利用其 WriteMessage 方法。 在以下示例中,MyDependency 类是 IndexModel 类的依赖项:

 
public class IndexModel : PageModel
{
private readonly MyDependency _dependency = new MyDependency(); public void OnGet()
{
_dependency.WriteMessage("IndexModel.OnGet");
}
}

该类创建并直接依赖于 MyDependency 类。 代码依赖项(如前面的示例)会产生问题,应避免使用,原因如下:

  • 要用不同的实现替换 MyDependency,必须修改 IndexModel 类。
  • 如果 MyDependency 具有依赖项,则必须由 IndexModel 类对其进行配置。 在具有多个依赖于 MyDependency 的类的大型项目中,配置代码将分散在整个应用中。
  • 这种实现很难进行单元测试。

依赖关系注入通过以下方式解决了这些问题:

  • 使用接口或基类将依赖关系实现抽象化。
  • 在服务容器中注册依赖关系。 ASP.NET Core 提供了一个内置的服务容器 IServiceProvider。 服务通常已在应用的 Program.cs 文件中注册。
  • 将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时将其释放。

在示例应用中, 接口定义 WriteMessage 方法:

public interface IMyDependency
{
void WriteMessage(string message);
}

此接口由具体类型 MyDependency 实现:

public class MyDependency : IMyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
}
}

示例应用使用具体类型 MyDependency 注册 IMyDependency 服务。 AddScoped 方法使用范围内生存期(单个请求的生存期)注册服务。

using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddScoped<IMyDependency, MyDependency>(); var app = builder.Build();

在示例应用中,请求 IMyDependency 服务并用于调用 WriteMessage 方法:

public class Index2Model : PageModel
{
private readonly IMyDependency _myDependency; public Index2Model(IMyDependency myDependency)
{
_myDependency = myDependency;
} public void OnGet()
{
_myDependency.WriteMessage("Index2Model.OnGet");
}
}

通过使用 DI 模式,控制器或 Razor 页面:

  • 不使用具体类型 MyDependency,仅使用它实现的 IMyDependency 接口。 这样可以轻松地更改实现,而无需修改控制器或 Razor 页面。
  • 不创建 MyDependency 的实例,这由 DI 容器创建。

这样就做到了完美解耦,我们的控制器也就不再依赖于某个具体的对象了。

我们书写这样的代码,也符合设计模式中的:继承原则,单一职责原则,开放封闭原则,依赖倒转原则。

上述说的设计模式原则简单介绍下:

关于继承无需多说

所谓单一职责原则是指:就一个类而言,应该仅有一个引起它变化的原因

所谓开闭原则是指:对于扩展是开放的,对于修改是封闭的(ASD原则)

依赖倒转原则是指:高层不应该依赖底层模块(强内聚,松耦合),就上述代码中的控制器(IndexModel、Index2Model)属于高层模块,接口及其实现类,服务注册类/方法(startup.cs中的ConfigureServices)属于底层模块。

参考博客:https://www.cnblogs.com/chenwolong/p/Scoped.html

微软文档:https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0

.Net依赖注入、控制反转的更多相关文章

  1. PHP关于依赖注入(控制反转)的解释和例子说明

    PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-20 10:12)   阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即 1111 ...

  2. Helloworld之Spring依赖注入/控制反转(DI/IoC)版

    Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...

  3. C#依赖注入控制反转IOC实现详解

    原文:C#依赖注入控制反转IOC实现详解 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. ...

  4. Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转

    原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...

  5. Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转

    小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...

  6. laravel5.2总结--服务容器(依赖注入,控制反转)

    1.依赖 我们定义两个类:class Supperman 和 class Power,现在我们要使用Supperman ,而Supperman 依赖了Power class Supperman { p ...

  7. 依赖注入&控制反转

    IoC——Inversion of Control  控制反转DI——Dependency Injection   依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依 ...

  8. Spring 依赖注入控制反转实现,及编码解析(自制容器)

    定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...

  9. MVC 依赖注入/控制反转

    http://www.cnblogs.com/cnmaxu/archive/2010/10/12/1848735.html http://www.cnblogs.com/artech/archive/ ...

  10. 马丁 福勒 Martin Fowler 关于依赖注入和反转控制的区别

    马丁 福勒 Martin Fowler 关于依赖注入和反转控制的区别 http://martinfowler.com/articles/injection.html 中文翻译:http://files ...

随机推荐

  1. <一>对象使用过程中背后调用了哪些方法

    代码1 #include <iostream> using namepspace std; class Test { public: Test(int a=10):ma(a){cout&l ...

  2. 3.8:使用R语言实现Apriori算法示例

    〇.目标 1.使用R语言实现Apriori算法完成关联规则挖掘:2.利用超市购物篮Groceries数据进行关联规则分析. 一.利用arules包加载Groceries数据集 二.探索和准备数据 三. ...

  3. Kubernetes(k8s)存储管理之数据卷volumes(五):动态制备-存储类StorageClass

    目录 一.系统环境 二.前言 三.静态制备和动态制备 四.存储类StorageClass 4.1 存储类StorageClass概览 4.2 StorageClass 资源 五.创建存储类Storag ...

  4. Django框架模板语法传值-过滤器-标签-自定义过滤器,标签,inclusion_tag

    目录 一:模版语法传值 1.模板语法两个书写方式 2.模板语法 3.测试模板语法是否可以把python支持的基本数据类型传入到前端 4.index.html 5.django模板语法取值方式 二:过滤 ...

  5. vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)

    https://blog.csdn.net/weixin_43374193/article/details/95594419 https://blog.csdn.net/harrisonz8/arti ...

  6. nuxt.js安装使用

    首先要学会看文档,https://www.nuxtjs.cn/guide/configuration 一.创建项目,并运行 终端运行 npx create-nuxt-app <项目名> ( ...

  7. [0x12] 132.小组队列

    题意 link(more:UVA540) 简化题意:对 \(n\) 个小组排队,每个小组有至多 \(m\) 个成员(每个成员有唯一编号 \(x\)),当一个人来到队伍时,如果队中有同组成员,直接插入其 ...

  8. Proxmark3 Easy 如何流畅的在Linux中操作?

    前言 Proxmark3 Easy可谓是国内能买到的比较便宜的RFID卡防设备了,曾在部分hv中出现. Proxmark3 Easy是国内简化的一种设备,利用的是较早的Proxmark3的开源,基础的 ...

  9. [编程基础] Python装饰器入门总结

    Python装饰器教程展示了如何在Python中使用装饰器基本功能. 文章目录 1 使用教程 1.1 Python装饰器简单示例 1.2 带@符号的Python装饰器 1.3 用参数修饰函数 1.4 ...

  10. tempdb日志文件暴增分析

    背景 某医院信息科接到CIS系统磁盘空间不足告警,通过排查发现tempdb的日志文件暴增,已经涨到了130G左右,并且还在持续增长中.需要我们紧急排查原因. 现象 登陆到服务器里,确实看到了如上所说, ...