跟我一起学.NetCore之依赖注入

前言

现阶段而言,依赖注入相关组件如果不会用一两个,感觉在Code的世界里肯定是落伍了,最起码得有工厂模式的思想,知道这样做的好处;提及到依赖注入,通常会关联出两个概念:Ioc(控制反转)和DI(依赖注入)

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

百度百科

个人理解:

IoC(控制反转):  就是将原先的new对象这个操作交由第三方容器,由容器统一创建对象并管理其创建对象的生命周期;

DI(依赖注入): 我理解其中“依赖”有两层意思:

  •     类与类之间的依赖关系;

  •     对象的创建依赖于容器;

    "注入":不用主动从容器中获取对象,由容器根据对象依赖关系自动注入;

 依赖注入:程序将对象控制权交给容器,统一依赖容器创建对象,类之间的依赖,也是通过容器自动注入;

注:注入的前提是要把对象的控制权交给容器;

依赖注入优点:

  •     轻松管理类及类之间的依赖;

  •     减少代码耦合性;

  •     提高代码维护性和可扩展性;

  •     由容器统一创建对象和管理生命周期;

好了,先不详细深究了,这里先说说.NetCore中自带的依赖注入框架怎么玩;

正文

    先看看.NetCore中的自带的依赖注入怎么用,先创建一个Asp.NetCore 程序:

    上图是模板程序,只在Action 方法中直接使用了模板中已经注入好_logger的对象,此对象通过构造函数的形式注入,刚开始接触的Asp.NetCore的小伙伴会疑问,都没注册对应服务,怎么会注入,其实在我们启动过程的时候简单说到过,框架会自动注入一些默认的服务,其中就用ILogger,用起来就是这么简单;

    .NetCore中依赖注入有几个关键的类型,简单介绍一下:

  • IServiceCollection:负责存储注册的服务,可以通过其扩展方法进行服务注册;

  • ServiceDescriptor:服务注册时的信息,如服务类型、实现类型、实例类型、生命周期等;

  • IServiceProvider: 理解是常说的容器,是IServiceCollection创建出来的,用来提供实例的;

  • IServiceScope:表示一个容器的子容器的生命周期;

通过以上可以简要理解注入的简要过程:

通过容器创建的出来的对象,根据不同的注入方式有以下三种生命周期:

  • Singleton(单例) :整个根容器的生命周期内是同一个对象;通过 services.AddSingleton()方法进行注册;

  • Scoped(作用域) :在容器或子容器的生命周期内,对象保持一致,如果容器释放掉,那就意味着对象也会释放掉;通过 services.AddScoped()方法进行注册;

  • Transient(瞬时) : 每次使用都会创建新的实例;通过 services.AddTransient()方法进行注册;

    注:services 是  IServiceCollection services ;

以下通过程序演示常用的注入方法及其对应的生命周期;在以上创建的项目中针对不同的生命周期添加不同的类型,里面没有任何代码,如下图;

    

    在Startup文件的ConfigureServices方法中进行注册,如下:

    注册完毕之后,在Controller中的Action方法就可以使用了,如下:

    通过对比每个对象的HashCode, 如果一样就代表是同一个对象,运行程序看结果(这里以项目的形式运行,在控制台中方便看输出):

    

    以上实例只是常规注册方式,还有以下常用注册方式,如下图;

    新增一个IUserService,方便后续演示

  

Asp.NetCore自带依赖注入的注册方式,如下:

   

增加一个Action方法,打了个断点运行调试:

其他注入方式就不一一运行演示了,这里主要演示排他注册的结果,如下:

所以结果成立

IUserService和IStudentService都注册了三次,但最终通过排他注册方式,最后成功的只一个和两个;

泛型注册方式,提供模板注册,如下:

先定义一个泛型:

注册,只能通过参数的形式注册:

使用方式和上面一样;

依赖注入其他操作:

两种常用注入方式:

构造函数注入:当注入的服务对象多个地方使用时,就用构造函数的形式注入;

[FromService]注入:当只是临时使用服务对象时,就用[FromService]注入;

总结

    .NetCore自带的注入常用用法差不多就这些,下一节说说作用域及容器创建对象之后的释放;

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

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

相关文章

跟我一起学.NetCore之依赖注入作用域和对象释放

前言上一小节简单阐述了依赖注入及Asp.NetCore中自带依赖注入组件的常规用法,其中提到容器管控了自己创建对象的生命周期,包含了三种生命周期:Singleton、Scoped、Transient, 对于Singleton、Transient相对于Scoped来说比较好理解…

leetcode738. 单调递增的数字

一:芭比Q了 又掉一个粉 啊呜呜呜呜呜 如果作为一个领导者来说,首先就是要以身作则,自己都做不到 ,那就没什么威信去要求手下人按照要求去做 二:题目 三:上码 class Solution { public:int monotoneIncreasingDigits(int n) {/**思路:1.这…

大揭秘| 我司项目组Gitlab Flow DevOps流程

长话短说,本文全景呈现我司项目组gitlab flow && devopsGit Flow定义了一个项目发布的分支模型,为管理具有预定发布周期的大型项目提供了一个健壮的框架。DevOps 强调的是团队通过自动化的工具协作和高效地沟通来完成软件的生命周期管理&#xf…

leetcode714.买卖股票的

一:题目 二&#xff1a;上码 class Solution { public:int maxProfit(vector<int>& prices, int fee) {/**思路:*/int ans 0;int minPrice prices[0];//最低时买入for(int i 1; i < prices.size(); i) {//低价买入minPrice min(minPrice,prices[i]);if(price…

C++ 学习之旅(1)——编译器Compiler

简单来说&#xff0c;由C代码文件生成可执行文件的过程如下&#xff1a; #mermaid-svg-GQamCVEXMVkYEemz {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GQamCVEXMVkYEemz .error-icon{fill:#552222;}#mermaid-svg-…

掌握Rabbitmq几个重要概念,从一条消息说起

RabbitMQ 是功能强大的开源消息代理。根据官网称&#xff1a;也是使用量最广泛的消息队列。就像他的口号“Messaging that just works”&#xff0c;开箱即用使用简单&#xff0c;支持多种消息传输协议&#xff08;AMQP、STOMP、MQTT&#xff09;。一个应用程序或者服务如何使用…

122. 买卖股票的时机

一&#xff1a;题目 二&#xff1a;上码 class Solution { public:int maxProfit(vector<int>& prices) {/**思路:1.这里用的是贪心算法&#xff08;我们每隔两天计算一次赚的钱 只要大于0的话 那就是赚的&#xff09;2.我们手里最多只能有一只股票,所以我们可以当…

C++ 学习之旅(2)——链接器Linker

每一个.cpp文件经过编译之后都会生成对应的.obj文件&#xff0c;然后通过链接器把它们进行链接&#xff0c;最后就可以生成.exe可执行文件了。 举个例子&#xff0c;假设我们有一个 Math.cpp 文件和 Log.cpp 文件&#xff1a; Math.cpp #include <iostream>void Log(c…

使用 WPF 版简易 SIP 服务器向 GB28181 摄像头发送直播请求

使用 WPF 版简易 SIP 服务器向 GB28181 摄像头发送直播请求目录一、引言二、项目渊源三、软件使用及 SIP INVITE 流程(一) 注册和心跳(二) 直播 INVITE四、注意事项五、资源独立观察员 2020 年 9 月 16 日一、引言之前写过一篇博客《使用 GB28181.Solution ZLMediaKit MediaSe…

leetcode968. 监控二叉树

一:论语 这个有意思,我们可以从中得出的是&#xff0c;一个人过错 其实是潜意思决定的 行为见品质 但知错更改也是nice的 二:题目 三:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* Tr…

C++ 学习之旅(3)——头文件Header

我们知道&#xff0c;在 C 中&#xff0c;函数只能定义一次&#xff0c;而在 cpp 文件中如果想使用其他 cpp 文件中定义了的函数&#xff0c;就必须声明&#xff0c;这样才能通过编译&#xff0c;然后链接器才会在调用函数时找到该函数的定义。那么当函数声明很多的时候&#x…

虚虚实实,亦假亦真的 ValueTuple,绝对能眩晕你

一&#xff1a;背景 1. 讲故事前几天在写一个api接口&#xff0c;需要对衣物表进行分页查询&#xff0c;查询的output需要返回两个信息&#xff0c;一个是 totalCount,一个是 clothesList,在以前我可能需要封装一个 PagedClothes 类&#xff0c;如下代码:public class PagedClo…

C++ 学习之旅(4)——调试Debug

调试 Debug 程序&#xff0c;首先应该确保处于 Debug 模式而不是 Release 模式下&#xff0c;因为后者会优化你的程序&#xff0c;也就是对你的程序作出了改变&#xff0c;这样你很难找出问题所在。记得在 Debug 之前确保优化是已禁用的&#xff1a; 我们有以下的文件&#xff…

关于脑机接口该如何实现的考虑

脑机接口&#xff0c;已经是最近最热门的科技热点了&#xff0c;因为埃隆马斯克的炒作和推动&#xff08;炒作说的是他本人并不懂技术&#xff0c;宣传中有了很多夸大和不实之词&#xff0c;推动说的是因为他的炒作和带动&#xff0c;有了更多的资金进入了这个领域&#xff0c;…

C++ 学习之旅(5)——设置Setup文件目录

使用过Visual Studio的朋友都应该知道&#xff0c;VS对于编译后的obj文件以及链接生成的exe文件的存放方式是非常反人类的&#xff0c;所以我们有必要对这个设置进行更改。 首先要分清Filter和Folder的概念&#xff0c;在默认的文件目录中&#xff0c;我们看到的实际上是Filte…

JVM笔记详解之垃圾回收器

一&#xff1a;什么是垃圾回收机制&#xff08;GC&#xff09; 在C/C程序中&#xff0c;程序员在内存中主动开辟一段相应的空间来存值。由于内存是有限的&#xff0c;所以当程序不再需要使用该内存空间时&#xff0c;就需要销毁对象并释放其所占用的内存资源&#xff0c;好重新…

跟我一起学.NetCore之配置初体验

前言配置对于程序来说&#xff0c;绝对是必不可少&#xff0c;毕竟配置是应用或组件动态适应各种环境的最优方案&#xff0c;没有之一(我还年轻&#xff0c;我是这么认为的)&#xff1b;之前可能用的最多的配置源是命令行、文件(XML、Json、INI)&#xff0c;Web中对于Asp.Net程…

JVM笔记(JVM内存+垃圾回收器)详解

一:java代码的执行流程(引出JVM) 首先由程序员编写成.java文件然后由javac(java编辑器)将.java文件编译成.class文件.class文件可以在不同平台/操作系统上的JVM上执行再由JVM编译成可供不同操作系统识别的机器码&#xff08;0,1二进制&#xff09; 二:JVM来源 我们在下载JD…

跟我一起学.NetCore之Asp.NetCore中集成Autofac扩展

前言前两节针对.NetCore自带的依赖注入进行简要概述&#xff0c;对于日常开发的需求应该是能满足了&#xff0c;那为什么还需要引入第三方依赖注入组件呢&#xff0c;这里就从自带的依赖注入来分析&#xff0c;有什么样的需求满足不了&#xff1f;主要归纳为以下几点&#xff1…

C++ 学习之旅(7)——指针pointer

开门见山&#xff0c;如果把计算机的内存空间比作是一排房子&#xff0c;那指针就是房门号。指针实际上就是一个用来存储内存地址的整数&#xff0c;与类型没有关系&#xff0c;我可以定义一个void类型的指针&#xff1a; #include <iostream>int main() {int var 8;v…