当前位置: 首页 > article >正文

ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务

目录

一、ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务

1. app.Services

2. GetRequiredService()

3. Init()

二、应用场景

三、依赖注入使用拓展

1、使用场景

2、使用步骤

1. 定义服务接口和实现类

2. 注册服务到依赖注入容器

3. 使用依赖注入获取并执行服务

例子 1:在控制器中使用 DI 获取服务(控制器依赖注入)

例子 2:在中间件中使用 DI 获取服务(中间件依赖注入)

例子 3:在 Program.cs 中直接使用 DI 获取服务(项目启动获取服务)


一、ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务

今天看代码时候看到一句话,知识点接着学起来!!

await app.Services.GetRequiredService<InitService>().Init();

这句话是在 ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行某个服务的方法。

1. app.Services

appIApplicationBuilder 类型的对象,它用于配置请求处理管道。app.Services 获取的是 IServiceProvider,即服务提供者,用于解析和提供注册在依赖注入容器中的服务实例。

  • IServiceProvider 是 ASP.NET Core 中依赖注入(DI)机制的核心接口,用于从服务容器中解析已注册的服务。

2. GetRequiredService<InitService>()

GetRequiredService<T>()IServiceProvider 提供的方法,用于从 DI 容器中获取指定类型 T 的服务实例。

  • InitService 是某个自定义服务类(可能是应用程序启动时进行一些初始化操作的服务),通过 GetRequiredService<InitService>() 从 DI 容器中获取该服务的实例。

    • GetRequiredService<T>() 方法与 GetService<T>() 不同,它在容器中没有找到所请求的服务时,会抛出 InvalidOperationException 异常。相反,GetService<T>() 如果找不到服务,则会返回 null

3. Init()

InitService 类中有一个 Init 方法,它是一个自定义的方法,通常用于执行一些初始化任务(如数据库初始化、缓存加载、配置设置等)。

  • Init() 方法可能是一个异步方法,因此它被 await 关键字调用,表示它需要异步执行,执行完毕后,程序才能继续执行下去。

结合起来的含义

  • 从 ASP.NET Core 的依赖注入容器中获取 InitService 实例。
  • 调用 InitService 中的 Init 方法来进行一些初始化工作。
  • 使用 await 关键字,确保初始化操作完成之后,才继续执行后续的代码。

二、应用场景

这行代码常常出现在 ASP.NET Core 应用的启动阶段,特别是在 Program.csStartup.cs 文件中,通常用于执行应用启动时需要的一些初始化任务。例如:

  • 初始化数据库。
  • 加载应用配置。
  • 设置缓存或其他外部资源。

思考:

从这句话中 我们可以大致猜测,有一个类 类里边有一个Init方法:

public class InitService
{private readonly IMyDbContext _dbContext;public InitService(IMyDbContext dbContext){_dbContext = dbContext;}public async Task Init(){// 执行数据库初始化或其他启动任务await _dbContext.InitializeAsync();}
}

 因此,我们在 Program.cs 中,你可以使用

await app.Services.GetRequiredService<InitService>().Init();

来确保在应用启动时执行该初始化操作:

public class Program
{public static async Task Main(string[] args){var builder = WebApplication.CreateBuilder(args);// 注册服务builder.Services.AddScoped<InitService>();var app = builder.Build();// 在应用启动时执行初始化await app.Services.GetRequiredService<InitService>().Init();// 配置请求管道app.MapControllers();await app.RunAsync();}
}

三、依赖注入使用拓展

1、使用场景

在 ASP.NET Core 中,依赖注入(DI)是通过构造函数注入、属性注入或方法注入来实现的,通常我们会通过 IServiceProvider 来获取和执行某个服务。

一般有如下代码使用场景:

  • 构造函数注入:通过构造函数注入依赖的服务,最常见的 DI 方式。
  • 方法或属性注入:也可以使用方法或属性注入,但这些方法不如构造函数注入常见。
  • 中间件注入:ASP.NET Core 中间件也可以通过构造函数注入来获取 DI 容器中的服务。
  • IServiceProvider 获取服务:在一些情况下,可能需要在应用程序启动时或特定时刻获取服务,可以通过 IServiceProvider 来实现。

通过依赖注入,ASP.NET Core 提供了一个灵活且易于测试的架构,使得应用程序中的服务解耦并易于维护。

2、使用步骤

1. 定义服务接口和实现类

首先,我们定义一个简单的服务接口和它的实现类。

// 定义服务接口
public interface IMyService
{Task ExecuteAsync(string message);
}// 服务实现
public class MyService : IMyService
{public async Task ExecuteAsync(string message){await Task.Delay(1000);  // 模拟一些异步操作Console.WriteLine($"Executing MyService with message: {message}");}
}

2. 注册服务到依赖注入容器

Startup.csProgram.cs 中,我们需要将服务注册到 DI 容器中。通常,这些注册是在 ConfigureServices 方法中进行的。

public class Startup
{public void ConfigureServices(IServiceCollection services){// 注册 IMYService 接口及其实现类 MyServiceservices.AddSingleton<IMyService, MyService>();}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){// 省略其他中间件配置...}
}

3. 使用依赖注入获取并执行服务

假设我们在 ControllerMiddleware 中需要执行 IMyService,可以通过构造函数注入的方式获取服务并执行。

例子 1:在控制器中使用 DI 获取服务(控制器依赖注入)
// Controller 示例
public class HomeController : Controller
{private readonly IMyService _myService;// 通过构造函数注入 IMyServicepublic HomeController(IMyService myService){_myService = myService;}public async Task<IActionResult> Index(){await _myService.ExecuteAsync("Hello from HomeController");return View();}
}
例子 2:在中间件中使用 DI 获取服务(中间件依赖注入)

在 ASP.NET Core 中,中间件也是可以使用 DI 来获取服务的。下面是如何在中间件中执行服务的一个例子:

public class MyMiddleware
{private readonly RequestDelegate _next;private readonly IMyService _myService;// 通过构造函数注入 IMyServicepublic MyMiddleware(RequestDelegate next, IMyService myService){_next = next;_myService = myService;}public async Task InvokeAsync(HttpContext context){// 在中间件中执行 IMyServiceawait _myService.ExecuteAsync("Hello from MyMiddleware");// 调用下一个中间件await _next(context);}
}

Startup.cs 中注册该中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseMiddleware<MyMiddleware>();  // 注册自定义中间件
}
例子 3:在 Program.cs 中直接使用 DI 获取服务(项目启动获取服务)

在某些情况下,我们可能需要在应用启动时直接获取并执行某个服务。例如,在 Program.cs 文件中。

public class Program
{public static async Task Main(string[] args){var host = CreateHostBuilder(args).Build();// 获取 DI 容器中的服务并执行using (var scope = host.Services.CreateScope()){var myService = scope.ServiceProvider.GetRequiredService<IMyService>();await myService.ExecuteAsync("Hello from Program.cs");}await host.RunAsync();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});
}

相关文章:

ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务

目录 一、ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务 1. app.Services 2. GetRequiredService() 3. Init() 二、应用场景 三、依赖注入使用拓展 1、使用场景 2、使用步骤 1. 定义服务接口和实现类 2. 注册服务到依赖注入容器 3. 使用依赖注入获取并…...

Nginx知识

nginx 精简的配置文件 worker_processes 1; # 可以理解为一个内核一个worker # 开多了可能性能不好events {worker_connections 1024; } # 一个 worker 可以创建的连接数 # 1024 代表默认一般不用改http {include mime.types;# 代表引入的配置文件# mime.types 在 ngi…...

CSES Missing Coin Sum

思路是对数组排序 设 S [ i ] S[i] S[i] 是数组的前缀和 R [ i ] R[i] R[i] 是递增排序后的数组 遍历数组&#xff0c;如果出现 S [ i − 1 ] 1 < R [ i ] S[i - 1] 1 < R[i] S[i−1]1<R[i]&#xff0c;就代表S[i - 1] 1是不能被合成出来的数字 因为&#xff1a…...

nth_element函数——C++快速选择函数

目录 1. 函数原型 2. 功能描述 3. 算法原理 4. 时间复杂度 5. 空间复杂度 6. 使用示例 8. 注意事项 9. 自定义比较函数 11. 总结 nth_element 是 C 标准库中提供的一个算法&#xff0c;位于 <algorithm> 头文件中&#xff0c;用于部分排序序列。它的主要功能是将…...

Hot100之双指针

283移动零 题目 思路解析 那我们就把不为0的数字都放在数组前面&#xff0c;然后数组后面的数字都为0就行了 代码 class Solution {public void moveZeroes(int[] nums) {int left 0;for (int num : nums) {if (num ! 0) {nums[left] num;// left最后会变成数组中不为0的数…...

DeepSeek-R1论文研读:通过强化学习激励LLM中的推理能力

DeepSeek在朋友圈&#xff0c;媒体&#xff0c;霸屏了好长时间&#xff0c;春节期间&#xff0c;研读一下论文算是时下的回应。论文原址&#xff1a;[2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 摘要&#xff1a; 我们…...

p1044 栈

两种递推细节不同 1,将1和n在序列末尾的情况单独放出来处理&#xff0c;因为dp[0]0&#xff1b; 2,将所有情况统一处理&#xff0c;这种情况就要要求dp[1]1; 这里的n在解题中可以看做是元素数量 思路是&#xff0c;根据出栈最后一个元素,统计它前面的元素数量的输出序列数和…...

群晖Alist套件无法挂载到群晖webdav,报错【连接被服务器拒绝】

声明&#xff1a;我不是用docker安装的 在套件中心安装矿神的Alist套件后&#xff0c;想把夸克挂载到群晖上&#xff0c;方便复制文件的&#xff0c;哪知道一直报错&#xff0c;最后发现问题出在两个地方&#xff1a; 1&#xff09;挂载的路径中&#xff0c;直接填 dav &…...

three.js+WebGL踩坑经验合集(6.2):负缩放,负定矩阵和行列式的关系(3D版本)

本篇将紧接上篇的2D版本对3D版的负缩放矩阵进行解读。 (6.1):负缩放&#xff0c;负定矩阵和行列式的关系&#xff08;2D版本&#xff09; 既然three.js对3D版的负缩放也使用行列式进行判断&#xff0c;那么&#xff0c;2D版的结论用到3D上其实是没毛病的&#xff0c;THREE.Li…...

【ubuntu】双系统ubuntu下一键切换到Windows

ubuntu下一键切换到Windows 1.4.1 重启脚本1.4.2 快捷方式1.4.3 移动快捷方式到系统目录 按前文所述文档&#xff0c;开机默认启动ubuntu。Windows切换到Ubuntu直接重启就行了&#xff0c;而Ubuntu切换到Windows稍微有点麻烦。可编辑切换重启到Windows的快捷方式。 1.4.1 重启…...

力扣第149场双周赛

文章目录 题目总览题目详解找到字符串中合法的相邻数字重新安排会议得到最多空余时间I 第149场双周赛 题目总览 找到字符串中合法的相邻数字 重新安排会议得到最多空余时间I 重新安排会议得到最多空余时间II 变成好标题的最少代价 题目详解 找到字符串中合法的相邻数字 思…...

在线课堂小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

https的原理

HTTPS 的原理 HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;是一种通过计算机网络进行安全通信的传输协议。它在 HTTP 的基础上增加了 SSL/TLS 协议&#xff0c;以实现数据传输的安全性和完整性。以下是 HTTPS 的基本原理&#xff1a; 1. 基本概念 HTTP…...

当卷积神经网络遇上AI编译器:TVM自动调优深度解析

从铜线到指令&#xff1a;硬件如何"消化"卷积 在深度学习的世界里&#xff0c;卷积层就像人体中的毛细血管——数量庞大且至关重要。但鲜有人知&#xff0c;一个简单的3x3卷积在CPU上的执行路径&#xff0c;堪比北京地铁线路图般复杂。 卷积的数学本质 对于输入张…...

Flask 使用Flask-SQLAlchemy操作数据库

username db.Column(db.String(64), uniqueTrue, indexTrue); password db.Column(db.String(64)); 建立对应关系 如果是多对多关系就建一张表&#xff0c;关联两个表的id role_id db.Column(db.Integer, db.ForeignKey(‘roles.id’)) ‘’’ 帮助作关联查询 relati…...

[EAI-023] FAST,机器人动作专用的Tokenizer,提高VLA模型的能力和训练效率

Paper Card 论文标题&#xff1a;FAST: Efficient Action Tokenization for Vision-Language-Action Models 论文作者&#xff1a;Karl Pertsch, Kyle Stachowicz, Brian Ichter, Danny Driess, Suraj Nair, Quan Vuong, Oier Mees, Chelsea Finn, Sergey Levine 论文链接&…...

使用Pygame制作“太空侵略者”游戏

1. 前言 在 2D 游戏开发中&#xff0c;“太空侵略者”是一款入门难度适中、却能覆盖多种常见游戏机制的项目&#xff1a; 玩家控制飞船&#xff08;Player&#xff09;左右移动&#xff0c;发射子弹。敌人&#xff08;Enemy&#xff09;排列成一行或多行&#xff0c;从屏幕顶…...

《逆向工程核心原理》第三~五章知识整理

查看上一章节内容《逆向工程核心原理》第一~二章知识整理 对应《逆向工程核心原理》第三章到第五章内容 小端序标记法 字节序 多字节数据在计算机内存中存放的字节顺序分为小端序和大端序两大类 大端序与小端序 BYTE b 0x12; WORD w 0x1234; DWORD dw 0x12345678; cha…...

2025 AI行业变革:从DeepSeek V3到o3-mini的技术演进

【核心要点】 DeepSeek V3引领算力革命&#xff0c;成本降至1/20o3-mini以精准优化回应市场挑战AI技术迈向真正意义的民主化行业生态正在深刻重构 一、市场格局演变 发展脉络 2025年初&#xff0c;AI行业迎来重要转折。DeepSeek率先发布V3模型&#xff0c;通过革命性的架构创…...

SAP SD学习笔记28 - 请求计划(开票计划)之2 - Milestone请求(里程碑开票)

上一章讲了请求计划&#xff08;开票计划&#xff09;中的 定期请求。 SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求-CSDN博客 本章继续来讲请求计划&#xff08;开票计划&#xff09;的其他内容&#xff1a; Milestone请求(里程碑请求)。 目录 1&#xff0c;Miles…...

算法随笔_27:最大宽度坡

上一篇:算法随笔_26: 按奇偶排序数组-CSDN博客 题目描述如下: 给定一个整数数组 nums&#xff0c;坡是元组 (i, j)&#xff0c;其中 i < j 且 nums[i] < nums[j]。这样的坡的宽度为 j - i。 找出 nums 中的坡的最大宽度&#xff0c;如果不存在&#xff0c;返回 0 。 …...

SpringBoot+Vue的理解(含axios/ajax)-前后端交互前端篇

文章目录 引言SpringBootThymeleafVueSpringBootSpringBootVue&#xff08;前端&#xff09;axios/ajaxVue作用响应式动态绑定单页面应用SPA前端路由 前端路由URL和后端API URL的区别前端路由的数据从哪里来的 Vue和只用三件套axios区别 关于地址栏url和axios请求不一致VueJSPS…...

大白话讲清楚embedding原理

Embedding&#xff08;嵌入&#xff09;是一种将高维数据&#xff08;如单词、句子、图像等&#xff09;映射到低维连续向量的技术&#xff0c;其核心目的是通过向量表示捕捉数据之间的语义或特征关系。以下从原理、方法和应用三个方面详细解释Embedding的工作原理。 一、Embe…...

2025年1月22日(网络编程 udp)

系统信息&#xff1a; ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…...

【RAG】SKLearnVectorStore 避免使用gpt4all会connection err

gpt4all 列表中包含了多个开源的大模型,如 Qwen2.5、Llama 3、DeepSeek、Mistral 等,但 不包含 OpenAI 的 GPT-4o。GPT-4o 是 OpenAI 提供的闭源模型,目前只能通过 OpenAI API 或 ChatGPT 官方应用(网页版、移动端)访问,并不支持本地运行,也没有 GGUF 量化格式的模型文件…...

ios swift画中画技术尝试

继上篇&#xff1a;iOS swift 后台运行应用尝试失败-CSDN博客 为什么想到画中画&#xff0c;起初是看到后台模式里有一个picture in picture&#xff0c;去了解了后发现这个就是小窗口视频播放&#xff0c;方便用户执行多任务。看小窗口视频的同时&#xff0c;可以作其他的事情…...

Prometheus 中的 Exporter

在 Prometheus 生态系统中,Exporter 扮演着至关重要的角色,它们负责从不同的服务或系统中收集和暴露度量数据。本文将详细介绍 Exporter 的概念、类型以及如何有效使用它们将 Prometheus 集成到各种系统中进行监控。 什么是 Exporter? Exporter 是一段软件,它从应用程序或…...

玄奘的启示

今天没事&#xff0c;又看了一遍央视拍的《玄奘大师》&#xff08;程池、齐秦配乐版&#xff09;伪纪录片&#xff0c;很有感触。 古罗马哲学家塞内加说“人最可怕的事情莫过于死前只留下活过的岁数。” 他在《论生命之短暂》中这样写道&#xff1a;“生命并非短促&#xff0…...

车载以太网---数据链路层

在上一章节中&#xff0c;我们讲解了数据链路层与物理层的接口MIIM,在本章中我们主要介绍车载网络中的数据链路层。 目录 数据链路层与网络层的区别 数据链路层&#xff1a;负责“同一链路”或“局域网/子网”内的可靠传输 传输范围&#xff1a; 主要功能&#xff1a; 通路…...

文本复制兼容方案最佳实现落地。

文章目录 一、navigator.clipboard.writeText二、方案落地总结 一、navigator.clipboard.writeText navigator.clipboard.writeText 是一个Web API&#xff0c;它允许网页脚本将文本数据写入用户的系统剪贴板。这个API是异步的&#xff0c;并且设计用于提高安全性和用户体验&a…...