【C#】.net core 6.0 依赖注入生命周期

给自己一个目标,然后坚持一段时间,总会有收获和感悟!
对于.net core而言,依赖注入生命周期有三种瞬态(Transient)、作用域(Scoped)和单例(Singleton),无论使用哪种生命周期,都需要确保对象的线程安全性,并正确地处理依赖关系。

在这里插入图片描述

目录

  • 一、程序生命周期
    • 2.1、构造函数
    • 2.2、配置
    • 2.3、启动
    • 2.4、运行
    • 2.5、停止
    • 2.6、释放资源
  • 二、依赖注入生命周期
    • 2.1、瞬态生命周期
    • 2.2、作用域生命周期
    • 2.3、单例生命周期
  • 三、代码举例
    • 3.1、瞬态生命周期
    • 3.2、作用域生命周期
    • 3.3、单例生命周期
  • 四、自定义管理
  • 五、依赖注入原理

一、程序生命周期

在了解依赖注入的生命周期前,我们先建单了解下应用程序的生命周期,
在 .NET Core 6.0 中,应用程序的生命周期包括以下阶段:

2.1、构造函数

在应用程序启动时,会调用构造函数来创建主机(Host)对象。

2.2、配置

在构造函数之后,会调用配置方法来设置应用程序的配置,例如添加服务、配置中间件等。

2.3、启动

配置完成后,会调用启动方法来启动应用程序,包括启动 HTTP 服务器、启动后台服务等。

2.4、运行

应用程序开始监听请求并进行处理,这是应用程序的主要运行阶段。

2.5、停止

当应用程序接收到停止信号时(如收到终止命令或服务器关闭),会触发停止方法来执行一些清理操作。

2.6、释放资源

在停止之后,应用程序释放资源并进行善后工作,如关闭数据库连接、释放资源等。

除了上述阶段外,还可以通过使用生命周期中的事件钩子来添加自定义逻辑,以便在特定时刻执行某些代码。
需要注意的是,不同类型的应用程序(如控制台应用程序、Web 应用程序等)的生命周期可以有所不同,但上述阶段是通用的核心生命周期。

二、依赖注入生命周期

在 .NET Core 6.0 中,依赖注入服务的生命周期有三种:瞬态(Transient)、作用域(Scoped)和单例(Singleton)。

2.1、瞬态生命周期

在每次请求时都会创建一个新的实例,并在请求结束时立即销毁该实例,适用于轻量级的对象。这种生命周期可以通过
services.AddTransient 方法进行注册。

2.2、作用域生命周期

在每个 HTTP 请求处理期间,会使用同一个实例,请求结束时实例也会被销毁,适用于线程安全的对象,如 EF 上下文。这种生命周期可以通过
services.AddScoped 方法进行注册。

2.3、单例生命周期

在整个应用程序生命周期中只会创建一个实例,适用于被多处使用的对象,如配置信息、单例服务等。这种生命周期可以通过
services.AddSingleton 方法进行注册。

除了上述生命周期外,还可以通过 services.AddSingleton 方法传递一个工厂方法,以实现自定义的生命周期管理。
无论使用哪种生命周期,都需要确保对象的线程安全性,并正确地处理依赖关系。正确使用依赖注入可以提高代码的可测试性和可维护性,将对象的创建和销毁等生命周期管理交由 DI 容器负责,从而简化代码的编写。

三、代码举例

当使用 .NET Core 6.0 进行依赖注入时,可以使用以下代码示例来演示瞬态、作用域和单例生命周期

3.1、瞬态生命周期

public interface ITransientService
{
void DoSomething();
}

public class TransientService : ITransientService
{
private readonly Guid _id;

public TransientService()
{
    _id = Guid.NewGuid();
}

public void DoSomething()
{
    Console.WriteLine($"TransientService ID: {_id}");
}

}

// 在 Startup.cs 的 ConfigureServices 方法中添加以下代码:
services.AddTransient<ITransientService, TransientService>();

// 在需要使用服务的地方,使用构造函数注入:
public class MyController
{
private readonly ITransientService _transientService;

public MyController(ITransientService transientService)
{
    _transientService = transientService;
}

// 使用服务
public void MyAction()
{
    _transientService.DoSomething();
}

}

3.2、作用域生命周期

public interface IScopeService
{
void DoSomething();
}

public class ScopeService : IScopeService
{
private readonly Guid _id;

public ScopeService()
{
    _id = Guid.NewGuid();
}

public void DoSomething()
{
    Console.WriteLine($"ScopeService ID: {_id}");
}

}

// 在 Startup.cs 的 ConfigureServices 方法中添加以下代码:
services.AddScoped<IScopeService, ScopeService>();

// 在需要使用服务的地方,使用构造函数注入:
public class MyController
{
private readonly IScopeService _scopeService;

public MyController(IScopeService scopeService)
{
    _scopeService = scopeService;
}

// 使用服务
public void MyAction()
{
    _scopeService.DoSomething();
}

}

3.3、单例生命周期

public interface ISingletonService
{
void DoSomething();
}

public class SingletonService : ISingletonService
{
private readonly Guid _id;

public SingletonService()
{
    _id = Guid.NewGuid();
}

public void DoSomething()
{
    Console.WriteLine($"SingletonService ID: {_id}");
}

}

// 在 Startup.cs 的 ConfigureServices 方法中添加以下代码:
services.AddSingleton<ISingletonService, SingletonService>();

// 在需要使用服务的地方,使用构造函数注入:
public class MyController
{
private readonly ISingletonService _singletonService;

public MyController(ISingletonService singletonService)
{
    _singletonService = singletonService;
}

// 使用服务
public void MyAction()
{
    _singletonService.DoSomething();
}

}

以上示例展示了如何在 .NET Core 6.0 中注册和使用瞬态、作用域和单例生命周期的依赖注入服务。
根据实际需求,选择适合的生命周期以确保正确的对象创建和销毁,并维护正确的对象状态。

四、自定义管理

当通过 services.AddSingleton 方法传递一个工厂方法时,可以使用委托来创建自定义的生命周期管理。

  • 下面是一个示例代码:
    首先,定义一个自定义的服务类 CustomService:
    public class CustomService
    {
    public DateTime CreatedAt { get; }

    public CustomService()
    {
    CreatedAt = DateTime.Now;
    }
    }

然后,在应用程序启动时,注册该服务并传递一个工厂方法来实现自定义的生命周期管理:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(serviceProvider =>
{
// 创建 CustomService 对象,并进行自定义的处理
var customService = new CustomService();

        // 在此可以添加自定义的生命周期管理逻辑

        return customService;
    });

    // 其他服务的注册
    // ...
}

}

在上述示例中,通过 services.AddSingleton(serviceProvider => { … }) 方法向 DI 容器注册了一个 CustomService 类型的单例服务,传递了一个工厂方法作为参数。
在这个工厂方法中,我们可以自定义创建 CustomService 对象的方式,并进行额外的处理。
这样,当通过 DI 容器解析 CustomService 时,每次获取到的都是通过工厂方法创建的同一个实例,而且可以根据需要在工厂方法中进行自定义的生命周期管理操作。
需要注意的是,工厂方法可以接收一个 IServiceProvider 参数,以便在创建服务实例时获取其他已注册的服务。这在某些场景下可能会很有用。

五、依赖注入原理

在 .NET Core 6.0 中,依赖注入(DI)是一个重要的功能,它通过提供、解析和跟踪应用程序中的各种服务对象来帮助解耦和组织代码。
依赖注入的原理主要包括以下几个方面:
1.服务注册:在应用程序启动时,通过使用
IServiceCollection 接口的 AddTransient、AddScoped、AddSingleton 等方法将服务类型和其生命周期添加到 DI 容器中。
2.服务解析:当需要使用某个服务的实例时,可以通过 DI 容器提供的
IServiceProvider 接口的 GetRequiredService、GetService 等方法来获取该服务的实例,其中 T 是服务类型。
3.生命周期管理:DI 容器会根据服务的生命周期设置来控制服务对象的创建和销毁。根据服务的生命周期,可以使用
AddTransient、AddScoped、AddSingleton 方法注册瞬态、作用域和单例服务。

  • 瞬态(Transient)生命周期表示每次通过 DI 容器获取服务时都会创建一个新的实例。
  • 作用域(Scoped)生命周期表示在同一个作用域内(例如,相同的 HTTP 请求)获取服务时将使用同一个实例。
  • 单例(Singleton)生命周期表示整个应用程序中只创建一个实例,并且所有的请求都会使用同一个实例。
    1.依赖关系解析:DI 容器能够自动解析服务对象之间的依赖关系,即当需要解析某个服务时,DI 容器会自动创建该服务所依赖的其他服务实例,并将其注入到需要的位置上。
    2.服务扩展:通过扩展
    IServiceCollection 接口,可以自定义添加和配置服务,使得 DI 容器能够支持更多的功能和扩展。

总体而言,.NET Core 6.0 的依赖注入原理基于 DI 容器、服务注册、服务解析和生命周期管理,帮助开发者更好地组织和管理应用程序中的各种服务对象,提高代码的可扩展性、可测试性和松耦合性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【正则表达式】

概述 正则表达式又称规则表达式。&#xff08;英语&#xff1a;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。正则表达式并不仅限于某一种语…

传统船检已经过时?AR智慧船检来助力!!

想象一下&#xff0c;在茫茫大海中&#xff0c;一艘巨型货轮正缓缓驶过。船上的工程师戴着一副先进的AR眼镜&#xff0c;他们不再需要反复翻阅厚重的手册&#xff0c;一切所需信息都实时显示在眼前。这不是科幻电影的场景&#xff0c;而是智慧船检技术带来的现实变革。那么问题…

中间件系列 - Redis入门到实战(高级篇-多级缓存)

前言 学习视频&#xff1a; 黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 中间件系列 - Redis入门到实战 本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 学习目标 JVM进程缓存Lua语法入…

scikit-learn文档中的数据生成器

目录 1. make_classification: 2. make_regression: 3. make_blobs: 4. make_moons: 5.make_circles 6. make_sparse_coded_signal: 1. make_classification: 这是一个用于生成复杂二维数据的函数&#xff0c;通常用于可视化分类器的学习过程或者测试机器学习算法的性能…

学习笔记:数据挖掘与机器学习

文章目录 一、数据挖掘、机器学习、深度学习的区别&#xff08;一&#xff09;数据挖掘&#xff08;二&#xff09;机器学习&#xff08;三&#xff09;深度学习&#xff08;四&#xff09;总结 二、数据挖掘体系三、数据挖掘的流程四、典型的数据挖掘系统 一、数据挖掘、机器学…

在Ubuntu20.04配置PX4环境

目录 1.下载PX4源码2.安装PX4所有工具链3.编译PX4工程1.下载PX4源码 打开Ubuntu,Ctrl+Alt+T打开终端输入下面代码: git clone https://github.com/PX4/PX4-Autopilot.git --recursive出现上图中出现“Command ‘git’ not found, but can be installed with”,使用以下代码…

山景32位蓝牙DSP音频应用处理芯片—BP1048B2

由工采网代理的BP1048B2是山景推出的一款高性能32位DSP蓝牙音频应用处理器&#xff1b;该芯片拥有32位RISC内核&#xff0c;支持DSP指令&#xff0c;集成FPU支持浮点运算&#xff0c;可应用于蓝牙K歌宝、蓝牙便携式音箱、蓝牙拖箱、蓝牙SoundBar、包头式蓝牙耳机、各类蓝牙音频…

2013年第二届数学建模国际赛小美赛A题数学与经济灾难解题全过程文档及程序

2013年第二届数学建模国际赛小美赛 A题 数学与经济灾难 原题再现&#xff1a; 2008年的市场崩盘使世界陷入经济衰退&#xff0c;目前世界经济仍处于低迷状态&#xff0c;其原因是多方面的。其中之一是数学。   当然&#xff0c;并非只有金融界依赖于并非总是可靠的数学模型…

第2课 用FFmpeg读取rtmp流并显示视频

这节课我们开始利用ffmpeg和opencv来实现一个rtmp播放器。播放器的最基本功能其实就两个:显示画面和播放声音。在实现这两个功能前&#xff0c;我们需要先用ffmpeg连接到rtmp服务器&#xff0c;当然也可以打开一个文件。 1.压缩备份上节课工程文件夹为demo.rar&#xff0c;并修…

3DV 2024 Oral | SlimmeRF:可动态压缩辐射场,实现模型大小和建模精度的灵活权衡

目前大多数NeRF模型要么通过使用大型模型来实现高精度&#xff0c;要么通过牺牲精度来节省内存资源。这使得任何单一模型的适用范围受到局限&#xff0c;因为高精度模型可能无法适应低内存设备&#xff0c;而内存高效模型可能无法满足高质量要求。为此&#xff0c;本文研究者提…

数据仓库 基本信息

数据仓库基本理论 数据仓库&#xff08;英语&#xff1a;Data Warehouse&#xff0c;简称数仓、DW&#xff09;,是一个用于存储、分析、报告的数据系统。数据仓库的目的是构建面向分析的集成化数据环境&#xff0c;为企业提供决策支持&#xff08;Decision Support&#xff09…

redis中根据通配符删除key

redis中根据通配符删除key 我们是不是在redis中keys user:*可以获取所有key&#xff0c;但是 del user:*却不行这里我提供的命令主要是SCANSCAN 0 MATCH user:* COUNT 100使用lua保证原子性 SCAN参数描述 在示例中&#xff0c;COUNT 被设置为 100。这是一个防止一次性获取大…

仓储革新:AR技术引领物流进入智慧时代

根据《2022年中国物流行业研究&#xff1a;深度探析行业现状&#xff08;智能设备及智能软件&#xff09;》&#xff0c;报告中提及&#xff1a;“中国社会物流总额依然保持着较为良好的增长态势&#xff0c;年增速已恢复至常年平均水平。2021年社会物流总额细分中工业物流总额…

小机器人,电子锁,牙刷,表类开关,磁阀开关等一些安防直流驱动的选型介绍分析

安防监控是一门被人们日益重视的新兴行业&#xff0c;就目前发展来看&#xff0c;应用普及程度越来越广&#xff0c;科技含量也越来越高&#xff0c;几乎所有高新科技都可促进其发展&#xff0c;尤其是信息时代的来临&#xff0c;更为该行业的发展提供契机。其中安防领域最为典…

玩转MYSQL|详细分析mysql-MGR集群搭建

目录 1、简介 2、环境准备 2.1 数据库服务器规划 2.2 安装mysql5.7.20 2.3 设置hostname和ip映射 3、创建复制环境 3.1 服务器host68.cn 3.1.1 配置/etc/my.cnf 3.1.2 服务器host68.cn上建立复制账号&#xff1a; 3.1.3 在mysql服务器host68.cn上安装group replicatio…

OpenChat-3.5:70亿参数下的AI突破

引言 在对话AI的发展史上&#xff0c;OpenChat-3.5标志着一个新纪元的到来。拥有70亿参数的这一模型&#xff0c;不仅是对现有语言学习模型&#xff08;LLMs&#xff09;的重大改进&#xff0c;更是在多模态任务中树立了新的标准。 模型概述 OpenChat-3.5作为一款先进的多模…

修复Apache httpd中的SSL/TLS 协议信息泄露漏洞(CVE-2016-2183)

漏洞详情如下&#xff1a; 详细描述TLS是安全传输层协议&#xff0c;用于在两个通信应用程序之间提供保密性和数据完整性。 TLS, SSH, IPSec协商及其他产品中使用的IDEA、DES及Triple DES密码或者3DES及Triple 3DES存在大约四十亿块的生日界&#xff0c;这可使远程攻击者通过S…

【超图】SuperMap iClient3D for WebGL/WebGPU —— 数据集合并缓存如何控制对象样式

作者&#xff1a;taco 最近在支持的过程中&#xff0c;遇到了一个新问题&#xff01;之前研究功能的时候竟然没有想到。通常我们控制单个对象的显隐、颜色、偏移的参数都是根据对象所在的图层以及对象单独的id来算的。那么问题来了&#xff0c;合并后的图层。他怎么控制单个对象…

微信小程序开发系列-04获取用户图像和昵称

这个功能的实现对于我这个新手来说可谓是一波三折。该功能的实现经历了三个“版本”的迭代&#xff0c;我的运气不是很好&#xff0c;从第一个“版本”开始尝试&#xff0c;这篇文章也是记录下这个过程&#xff0c;以便其他新手能快速找到解决方案。 Gen1-getUserInfo 第一个…

openmediavault(OMV) (19)云相册(3)mt-photos

简介 MT Photos是一款为Nas用户量身打造的照片管理系统。通过AI技术,自动将您的照片整理、分类,包括但不限于时间、地点、人物、照片类型。可以在任何支持Docker的系统中运行它。详情可查看mtmt.tech官网,mt-photos是付费订阅使用的,也可以一次性付费永久使用,具体使用mt…