最通俗易懂的依赖注入与控制反转

这是一个关于 ASP.NET 6 依赖注入的系列文章。

在这个系列中,我们将了解到什么是依赖注入、控制反转,它能够做什么,以及我们为什么要使用它。

之后,我们会进一步了解 ASP.NET 6 依赖注入的生命周期、服务容器等重要概念。

最后,我们再深入了解服务作用域和更多的服务注册与注入方式。

69e0ec38c6bcbf0dc9ea5af92b9625c5.png

概述

依赖注入是 ASP.NET 框架的核心。

它主要提供两个核心功能:

  1. 「注册类型」,这些注册到依赖注入系统的类型,在 .NET 中有一个高大上的名字——服务。

    因为这些类型都是为了给系统提供某种服务,所以类型注册也叫服务注册。

  2. 「解析实例」,服务/类型被注册以后,就可以被同样注入到依赖注入系统中的其它服务/类型使用。

    如类型 A 依赖类型 B,类型 A 就可以通过依赖注入获取类型 B 的实例。

想要彻底理解依赖注入,我们就必须要对控制反转有所了解。

控制反转

依赖注入中有一个叫做容器的东西,也被称为 IoC(Inversion of Control - 控制反转)容器。

这个容器中保存着所有由依赖注入系统创建的实例,那么它为什么叫 IoC 容器呢?

「控制反转(IoC)是一种反转流、依赖和接口的方式,它把传统上由程序代码直接操控的对象的调用权交给第三方,通过第三方来实现对象组件的装配和管理。」

假设我们有这么一个场景,一个四、五岁的小朋友,想要吃东西。

如果他自己从冰箱里找东西吃,可能会造成一些不好的结果,比如可能会拿到无法直接直接食用的食物,或者忘记关冰箱门等灯。

fe57e0a25a8aebeb213670ce1c1e5e0e.png

你可以思考一下,一个四、五岁的小孩儿,自己去冰箱拿食物,甚至自己去加工食材,你是不是觉得这不太正常?

那么正常情况是什么样的呢?

作为一个四、五岁的小孩儿,只需要找父母陈述一下需求,比如"我饿了、我想吃XX",这个时候,父母就会做好他所需要的食物,然后拿给他。

从主动去冰箱拿(正转)食物,到你想要吃的食物而被动获得(反转),这其实就是一个对象调用权转移的过程。

前者是主动获取食物,后者是由父母,也就是第三方把食物给他,而他并不关心食物从哪来,以及怎么得来。

所谓的“控制反转”的概念就是「对组件对象控制权的转移,从程序代码本身转移到了代码之外的第三方。」

通俗地说,就是应用程序的用户代码不负责依赖对象的创建和维护,而是将它交给第三方来负责,这样控制权就由应用程序转移到了第三方,即控制权实现了所谓的反转。

例如类型 A 需要使用类型 B 的实例,类型 B 实例的创建并不由类型 A 自己来负责,而是通过第三方来创建。

那么它和依赖注入又有什么关系呢?

依赖注入

「依赖注入是 IoC 的一种实现方式,用来实现依赖的反转。」

在前面的场景中,一个四、五岁的小孩,想要吃东西。

他只需要陈述一下需求,父母就会做好他需要的食物(依赖),然后拿给他(注入)。

依赖注入不是目的,它只是实现控制反转的方式。

使用依赖注入的目的,是为了管理应用中复杂的依赖关系,它可以帮助我们开发出松散耦合、可维护、可测试的代码和程序。

现在,再让我们回顾一下控制反转的解释。

一种反转流、依赖和接口的方式,它把传统上由程序代码直接操控的对象的调用权交给第三方,通过第三方来实现对象组件的装配和管理。

这个描述中的第三方就是依赖注入中的控制系统。

IoC 容器

在小孩子吃东西的场景里,有一方扮演着 IoC 容器的角色,你们分析下是谁?

我想很多人的第一直觉是“父母”?

其实,不严谨的来说,冰箱才是扮演 IoC 容器的角色,父母则是扮演依赖注入中控制系统的角色。

IoC 容器是依赖注入中一个保存已创建实例的东西,如果实例已创建,并且具有有效的生命周期,那么控制系统会直接从 IoC 容器获取实例,否则才会创建实例。

冰箱中的东西,都是父母买回来放进去的,同样也需要他们从冰箱中拿出来。

「所谓依赖注入系统,本质上就是一个实现了类型注册、实例解析和实例生命周期管理的组件。」

关于生命周期的内容,我们会在该系列的下一篇文章中详细讨论。

如果你了解工厂模式,那么你可以简单的把为依赖注入系统看作是一个超级工厂。

b04b79aceac09b8464c5bf53628a8fcf.png

在 .NET 的依赖注入系统中,所有注册的类型,都被称为服务。

ASP.NET 中的组件,大都都需要通过依赖注入获取它所依赖的服务实例。

所以说整个 ASP.NET 框架,都是建立在依赖注入系统之上的,这也是开发 ASP.NET 应用的最基本的编程模式。

更多精彩内容,请关注我▼▼

9e9cf1ace065cc4eee0e0237c0d6a883.gif

如果喜欢我的文章,那么

在看和转发是对我最大的支持!

(戳下面蓝字阅读)
  • ASP.NET 6 中间件系列

15c47e275289599dc8629d442b485af1.png

推荐关注微信公众号:码侠江湖

                        a3b8e8b4cefb1d1f8904fb238f7ac9bb.png觉得不错,点个在看再走哟

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288910.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

word公式编辑器_论文查重算公式吗 公式怎样避免查重?

论文查重算公式吗 公式怎样避免查重?每一个毕业生想要毕业都要经过论文查重这一关,仅有通过了论文查重,才可以进入答辩。在论文检测的情况下,不少同学论文中一定会应用大批量的计算公式,且计算公式全部都是固定不动的&#xff0c…

adb logcat 查看日志

使用 logcat 命令 查看和跟踪系统日志缓冲区的命令logcat的一般用法是&#xff1a; [adb] logcat [<option>] ... [<filter-spec>] ... 下文介绍过滤器和命令选项&#xff0c;详细内容可参见Listing of logcat Command Options。 可以在开发机中通过远程shell的方式…

小程序 - 学习笔记

一、小程序文档笔记 默认开发目录 开发目录解析 1.  app.js、app.json、app.wxss 这三个文件必须有不能删掉。 一个小程序主体部分由这三个文件组成&#xff0c;而且必须放在项目的根目录 js后缀的是脚本文件&#xff0c;调用小程序框架提供的 API—— API 文档json后缀的文件…

【C语言简单说】九:输入

到了下午了&#xff0c;上着班发现没啥事情做… 又来码博客了 ↖(▔&#xff3e;▔)↗ 这一小节我们来说说输入吧。突然想总结以下if语句的&#xff0c;结果发现&#xff0c;还有一个输入没说&#xff1b;之前是不是说过了输出&#xff1f;就是printf这个&#xff0c;现在还有…

java 优秀源码_想要快速进阶Java架构师?这份超强(长)学习计划单 请签收!...

优秀工程师的成长之路就是一条不断打怪升级之路的“修仙之路”&#xff01;而Java程序员一向比别人更难&#xff0c;如果说大家都在修仙的话&#xff0c;java程序员简直神似“剑修”&#xff0c;入行枯燥精通难&#xff0c;要想变得强大&#xff0c;需要能力也需要运气&#xf…

Web Api如何传递POST请求

这里记录一次Web Api传递post请求的例子&#xff0c;由于使用了默认工程的例子&#xff0c;方法名的参数值标记头为FromBody的形式&#xff0c;如下图所示的调用&#xff1a; 调用方式&#xff1a; 那么如果要两个以上的参数如何去实现&#xff0c;这种方式是不行的&#xff0c…

AOT和单文件发布对程序性能的影响

前言这里先和大家介绍一下.NET一些发布的历史&#xff0c;以前的.NET框架原生并不支持最终编译结果的单文件发布&#xff08;需要依赖第三方工具&#xff09;&#xff0c;我这里新建了一个简单的ASP.NET Core项目&#xff0c;发布以后的目录就会像下图这样&#xff0c;里面包含…

无法识别的属性“targetFramework”。请注意属性名称区分大小写。

asp.net部署出错(targetFramework无法识别) 今天尝试着部署了一个基于Framework4.0的web项目&#xff0c;途中发生了一点小小的意外。报的错误是Web.Config配置文件中的 targetFramework属性无法识别。后来查了一下发现在站点中部署的Web使用的是基于.Net Framework2.0的Applic…

.NET点滴:说说Middleware构造中获取不到Scoped服务的问题

今天小桂问我&#xff1a;“为什么中间件的构造函数里不能使用scope的生命周期类型啊&#xff1f;”&#xff0c;那就用实例来得到答案吧&#xff0c;先看小桂说的情况&#xff0c;是报错的&#xff1a;var builder WebApplication.CreateBuilder(args);builder.Services.AddS…

Java游戏有易筋经_当年武侠游戏中绝世秘籍易筋经!重置游戏几十次,玩家才终于找到?...

原标题&#xff1a;当年武侠游戏中绝世秘籍易筋经&#xff01;重置游戏几十次&#xff0c;玩家才终于找到&#xff1f;在金庸的笔下产生过诸多绝世武学&#xff0c;其中最常被人提及的莫过于少林绝学易筋经。这部由达摩祖师于嵩山少林寺面壁9年留下的武学经书&#xff0c;亦是武…

微软是如何解决 PC 端程序多开问题的——内部实现

前言上次&#xff0c;我们通过《引用 Microsoft.VisualBasic 解决程序多开的问题》。虽然它非常简单&#xff0c;但是仅适用于 WinForm 应用程序&#xff0c;而且还需要引用不常用的Microsoft.VisualBasic类库。因此&#xff0c;我们决定深挖一下&#xff0c;看看具体是如何实现…

svn之回滚到指定版本

1 问题 我们用svn下载了最新的代码&#xff0c;但是我们需要回退到制定的版本 2 操作 我们先svn showlog 找到对应的版本号 如果用的是svn图形界面客户端 我们点击关联svn项目的鼠标右键&#xff0c;然后有个update to reversion 写上相应的版本即可

【C语言简单说】十二:逻辑运算符

**总觉得今天更两节就好了。 (&#xffe3;.&#xffe3;) ** 困。。。(&#xffe3;.&#xffe3;) \ 今天我们来加深if的使用&#xff0c;我们来讲解运算符&&和||&#xff0c;一个叫做 与&& 一个叫做 或&&&#xff1b;我们先来说 && 我们…

正则匹配字符串无匹配不到_实现简单正则表达式匹配

这是facebook的面试题实现包含以下特殊字符的正则表达匹配“.” 匹配任意一个字符“*” 匹配任意多个前面的字符例如给定正则表达“ra.”和字符串“ray”你的函数应该返回true&#xff0c;但是仍用这个正则匹配另一个字符串“raymond”应当返回false给定正则表达“.*at”和字符…

【C语言简单说】十三:逻辑运算符||

&#xff08;﹏&#xff09;~ 更完睡觉。 这一节我们来说说逻辑或||&#xff0c;其实很简单的&#xff0c;既然你们理解了第一个逻辑与&#xff0c;那么逻辑或就没什么难度了。 我们说过逻辑与就像我们的并列关系&#xff0c;例如我们吃了苹果和李子。我们现在的逻辑或呢&a…

HQ-day2 C#语言基础

今天主要学习了C#的一些语言基础。 主要有&#xff1a;输入、输出。 一丶输入Console.readline(); 输入语句 输出console.write(); 输出语句 Console.writeline(); 输出语句自动换行 注释 CtrlK 然后 按C &#xff0c;注释选中部分 CtrlK 然后 按U&#xff0c; 取消注释 二、…

【C语言简单说】十三:变量的生命周期

这次我们就来说说生命周期的问题。其实声明周期的意思就是他这个变量的作用范围&#xff0c;啥是作用范围&#xff1f;唔。。。看我举例子吧&#xff0c;意会&#xff0c;意会。。。 首先&#xff0c;我想问一下你们&#xff0c;如果你们校长叫做小明&#xff0c;你们班也有一…

ASP.NET 6 中间件系列 - 条件中间件

这篇文章是 ASP.NET 6 中间件系列文章的第 4 部分。到目前为止&#xff0c;我们已经介绍了 ASP.NET 6 中间件的基础知识&#xff0c;展示了如何创建自定义中间件类&#xff0c;并讨论了中间件执行顺序的重要性。在本系列的最后一部分中&#xff0c;我们将展示在管道中有条件地执…

【C语言简单说】十四:for循环

说到了循环&#xff0c;我们的内容也就差不多了&#xff0c;此内容并不深入讲解太多东西&#xff0c;大家学习完&#xff0c;如果要深入的话可以查看相关书籍&#xff0c;详细大家学习完后可能会觉得看书上说的可能就看懂了。 可能会有人说为什么不说进制&#xff1f;或者说位…

使用RxJava从多个数据源获取数据

试想&#xff0c;需要一些动态数据的时候&#xff0c;只要每次都请求网络就可以了。但是&#xff0c;更有效率的做法是&#xff0c;把联网得到的数据&#xff0c;缓存到磁盘或内存。 具体的说&#xff0c;计划如下&#xff1a; 偶尔的联网操作&#xff0c;只为获取最新数据。 …