C# “依赖注入” 中的 “三种生命周期”

news/2024/10/17 17:16:07/

🚀简介

依赖注入(Dependency Injection,简称DI)是一种实现控制反转(IoC)的技术,用于减少代码之间的耦合度。通过依赖注入,一个类可以从外部获取其依赖的对象,而不是自己创建。这样可以使得代码更加模块化,更易于测试和维护。

🐳依赖注入的生命周期主要有以下三种:

  1. Transient:每次请求都会创建一个新的实例。这是最常见的生命周期选项。
  2. Scoped:在同一次请求中始终返回同一实例。如果在不同的请求中,将会创建一个新的实例。
  3. Singleton:每次请求都返回同一个实例,即在首次请求时创建的实例。

🚀安装NuGet包

首先,我们先安装 Microsoft.Extensions.DependencyInjection:这是Microsoft提供的依赖注入框架。

🚀Transient

创建一个类,包含一个属性(Name)和一个方法(SayHi)

public class TestServicesImp
{public string Name { get; set; }public void SayHi(){Console.WriteLine("Hello:"+Name);}
}

👻通过ServiceCollection创建了一个服务容器,然后通过AddTransient方法将TestServicesImp类型注册到这个服务容器中。这里使用的是瞬时生命周期,也就是每次从容器中获取TestServicesImp类型时,都会创建一个新的实例。

public class Program
{public static void Main(string[] args){var serviceCollection = new ServiceCollection();serviceCollection.AddTransient<TestServicesImp>();using (ServiceProvider sp = serviceCollection.BuildServiceProvider()){var t1 = sp.GetService<TestServicesImp>();t1.Name = "张三";t1.SayHi();var t2 = sp.GetService<TestServicesImp>();t2.Name = "李四";t2.SayHi();var referenceEquals = object.ReferenceEquals(t1, t2);Console.WriteLine(referenceEquals);}}
}

运行结果!因为在瞬时生命周期中,每次获取服务都会创建新的实例。 因此通过object.ReferenceEquals方法比较了t1和t2是否是同一个实例,结果会输出false

🚀 Scoped

我们将上面代码中的服务注册AddTransient方法换成AddScoped,然后t2.SayHi();换成t1.SayHi();,再试一次。

    public static void Main(string[] args){var serviceCollection = new ServiceCollection();serviceCollection.AddScoped<TestServicesImp>();using (ServiceProvider sp = serviceCollection.BuildServiceProvider()){var t1 = sp.GetService<TestServicesImp>();t1.Name = "张三";t1.SayHi();var t2 = sp.GetService<TestServicesImp>();t2.Name = "李四";t1.SayHi();var referenceEquals = object.ReferenceEquals(t1, t2);Console.WriteLine(referenceEquals);}}

发现这次的比较结果为true,并且第二次调用SayHi也是使用t1,但依然输出了李四,因此可以得出,两次获取服务得到的是同一个实例。

 👻我们对代码再进行改造一下,创建一个新的服务作用域,通过这个作用域的ServiceProvider对象获取了另一个TestServicesImp的实例t2。

    public static void Main(string[] args){var serviceCollection = new ServiceCollection();serviceCollection.AddScoped<TestServicesImp>();using (ServiceProvider sp = serviceCollection.BuildServiceProvider()){var t1 = sp.GetService<TestServicesImp>();t1.Name = "张三";using (IServiceScope scope = sp.CreateScope()){var t2 = scope.ServiceProvider.GetService<TestServicesImp>();t2.Name = "李四";t1.SayHi();t2.SayHi();var referenceEquals = object.ReferenceEquals(t1, t2);Console.WriteLine(referenceEquals);}}}

因为它们是在不同的Scope中获取的,所以这次的结果是false

 

🚀Singleton 

我们将服务注册AddScoped方法,换成AddSingleton,然后再执行一次

    public static void Main(string[] args){var serviceCollection = new ServiceCollection();serviceCollection.AddSingleton<TestServicesImp>();using (ServiceProvider sp = serviceCollection.BuildServiceProvider()){var t1 = sp.GetService<TestServicesImp>();t1.Name = "张三";using (IServiceScope scope = sp.CreateScope()){var t2 = scope.ServiceProvider.GetService<TestServicesImp>();t2.Name = "李四";t1.SayHi();t2.SayHi();var referenceEquals = object.ReferenceEquals(t1, t2);Console.WriteLine(referenceEquals);}}}

在输出结果中很显然可以看出使用AddSingleton注册服务,每次请求都返回同一个实例


http://www.ppmy.cn/news/1185694.html

相关文章

力扣每日一题82:删除排序链表中的重复元素||

题目描述&#xff1a; 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5]示例 2&#xff1a; 输入&…

【c++|opencv】一、基础操作---1.图像读取

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 有关c操作opencv记录 1. 正文 1.1 图像读取、显示、保存 // 读取、显示、保存图像#include <opencv2/opencv.hpp> #include <iostream>us…

向量数据库和普通关系型数据库的区别,LAXCUS支持哪种数据库?

这是一位Laxcus用户在后台的提问&#xff0c;贴出来供大家参考&#xff1a; 1. 向量数据库与传统的关系型数据库主要有以下几个区别&#xff1a; 数据类型&#xff1a;向量数据库专门用于存储和查询向量数据&#xff0c;而传统数据库可以存储各种类型的数据&#xff0c;如文本…

有关企业链表中数据类型的强制转换

From ChatGPT struct LinkNode {LinkNode* next; };struct LinkList {LinkNode node;int val 0; };void inti() {LinkList linkList;LinkNode* node (LinkNode*)(&linkList); }在提供的代码中&#xff0c;LinkNode 和 LinkList 是两个不同的结构体&#xff0c;但它们共享…

系统架构设计之云原生架构

云原生架构 一. 云原生技术介绍二. 传统架构模式 VS 云原生架构模式三. 云原生架构反模式四. 云原生架构设计原则 其它相关推荐&#xff1a; 软考系统架构之案例篇(架构设计相关概念) 系统架构之微服务架构 系统架构设计之微内核架构 鸿蒙操作系统架构 所属专栏&#xff1a;系统…

不知道怎么显示长标题?这里有小技巧,让你的内容更简洁明了!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; 文章内容 ⭐ 写在最后 ⭐…

openpnp - Warning - Unknown firmware

文章目录 openpnp - Warning - Unknown firmware概述笔记https://github.com/openpnp/openpnp/wiki/Motion-Controller-Firmwares备注END openpnp - Warning - Unknown firmware 概述 接上飞达控制板后, 显示未知固件的警告 开始没看源码之前, 总以为是回答的版本号不合适, …

微信投票小程序源码系统+多模板一键替换 带完整的部署教程

随着微信小程序的普及&#xff0c;越来越多的企业和活动组织者选择使用微信投票小程序来实现快速、高效的投票系统。然而&#xff0c;对于许多非技术用户来说&#xff0c;开发和部署一个投票小程序可能会面临一定的困难。下面罗峰就来给大家分享一款微信投票小程序源码系统&…