.Net依赖注入、控制反转
依赖项是指另一个对象所依赖的对象。 使用其他类所依赖的 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依赖注入、控制反转的更多相关文章
- PHP关于依赖注入(控制反转)的解释和例子说明
PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-20 10:12) 阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即 1111 ...
- Helloworld之Spring依赖注入/控制反转(DI/IoC)版
Helloworld之Spring依赖注入/控制反转(DI/IoC)版 作者:雨水, 日期:2014-10-29 摘要:本文主要用于培训刚開始学习的人理解Spring中的依赖注入的基本概念. 先介绍依 ...
- C#依赖注入控制反转IOC实现详解
原文:C#依赖注入控制反转IOC实现详解 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. ...
- Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转
原文地址:http://blog.csdn.net/wangyang1354/article/details/50757098 我们经常会遇到这样一种情景,就是在我们开发项目的时候经常会在一个类中调用 ...
- Benefits of Using the Spring Framework Dependency Injection 依赖注入 控制反转
小结: 1. Dependency Injection is merely one concrete example of Inversion of Control. 依赖注入是仅仅是控制反转的一个具 ...
- laravel5.2总结--服务容器(依赖注入,控制反转)
1.依赖 我们定义两个类:class Supperman 和 class Power,现在我们要使用Supperman ,而Supperman 依赖了Power class Supperman { p ...
- 依赖注入&控制反转
IoC——Inversion of Control 控制反转DI——Dependency Injection 依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依 ...
- Spring 依赖注入控制反转实现,及编码解析(自制容器)
定义: 在运行期,由外部容器动态的将依赖对象动态地注入到组件中. 两种方式: 手工装配 -set方式 -构造器 -注解方式 自动装配(不推荐) 1利用构造器 2set方法注入 dao: package ...
- MVC 依赖注入/控制反转
http://www.cnblogs.com/cnmaxu/archive/2010/10/12/1848735.html http://www.cnblogs.com/artech/archive/ ...
- 马丁 福勒 Martin Fowler 关于依赖注入和反转控制的区别
马丁 福勒 Martin Fowler 关于依赖注入和反转控制的区别 http://martinfowler.com/articles/injection.html 中文翻译:http://files ...
随机推荐
- 【每日一题】【树的dfs递归,返回多次,注意都遍历完后才最终返回】2022年1月6日-112. 路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum .判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum .如果存在,返回 tr ...
- 深入理解 MySQL 的事务隔离级别和 MVCC 机制
前言 我们都知道 MySQL 实现了 SQL 标准中的四个隔离级别,但是具体是如何实现的可能还一知半解,本篇博客将会从代码层面讲解隔离级别的实现方式,下面进入正题. 事务 考虑这样一个场景:博主向硝子 ...
- Javascript | 模拟mvc实现点餐程序
MVC模式是一个比较成熟的开发模式.M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.其中,View的定义比较清晰,就是用 ...
- Jmeter——循环控制器中实现Counter计数器的次数重置
近期在使用Jmeter编写个辅助测试的脚本,用到了多个Loop Controller和Counter. 当时想的思路就是三个可变的数量值,使用循环实现:但第三个可变值的数量次数,是基于第二次循环中得到 ...
- [常用工具] cvat安装与使用指北
cvat是一个非常好用的标注工具,但是也是非常难以安装的标注工具,所以本文简单讲一讲如何安装与使用cvat.cvat最好在ubuntu18.04安装,windows平台安装难度很大,然后在其他平台使用 ...
- [R语言] R语言快速入门教程
本文主要是为了从零开始学习和理解R语言,简要介绍了该语言的最重要部分,以快速入门.主要参考文章: R-Tutorial R语言程序的编写需要安装R或RStudio,通常是在RStudio中键入代码.但 ...
- python之路30 网络编程之初识并发编程1
并发编程理论 研究网络编程其实就是在研究计算机的底层原理及发展史 """ 计算机中真正干活的是CPU """ 操作系统发展史 1.穿孔卡片阶 ...
- 《STL源码剖析》STL的双层配置器
SGI STL第一级配置器: template<int inst> class __malloc_alloc_template{...}; 其中: 1.allocate()直接使用mall ...
- P8773 [蓝桥杯 2022 省 A] 选数异或
题面 给定一个长度为 \(n\) 的数列 \(A_{1}, A_{2}, \cdots, A_{n}\) 和一个非负整数 \(x\), 给定 \(m\) 次查询, 每次询问能否从某个区间 \([l, ...
- C# lock 、 Monitor Wait、Pulse和PulseAll 的区别和用法(转载)
1.Monitor.Wait方法当线程调用 Wait 时,它释放对象的锁并进入对象的等待队列,对象的就绪队列中的下一个线程(如果有)获取锁并拥有对对象的独占使用.Wait()就是交出锁的使用权,使线程 ...