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

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. 使用依赖注入获取并…...

leetcode——验证二叉搜索树(java)

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含小于当前节点的数。 节点的右子树只包含 大于 当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a; 输入…...

搜索引擎快速收录:关键词布局的艺术

本文来自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/21.html 搜索引擎快速收录中的关键词布局&#xff0c;是一项既精细又富有策略性的工作。以下是对关键词布局艺术的详细阐述&#xff1a; 一、关键词布局的重要性 关键词布局影响着后期页面…...

VLN视觉语言导航基础

0 概述 视觉语言导航模型旨在构建导航决策模型 π π π&#xff0c;在 t t t时刻&#xff0c;模型能够根据指令 W W W、历史轨迹 τ { V 1 , V 2 , . . . , V t − 1 } \tau\{V_1,V_2,...,V_{t-1}\} τ{V1​,V2​,...,Vt−1​}和当前观察 V t { P t , R t , N ( V t ) } V_…...

4 Hadoop 面试真题

4 Hadoop 面试真题 1. Apache Hadoop 3.0.02. HDFS 3.x 数据存储新特性-纠删码Hadoop面试真题 1. Apache Hadoop 3.0.0 Apache Hadoop 3.0.0在以前的主要发行版本&#xff08;hadoop-2.x&#xff09;上进行了许多重大改进。 最低要求的Java版本从Java 7增加到Java 8 现在&…...

java练习(2)

回文数&#xff08;题目来自力扣&#xff09; 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整…...

vscode命令面板输入 CMake:build不执行提示输入

CMake&#xff1a;build或rebuild不编译了&#xff0c;弹出:> [Add a new preset] , 提示输入发现settings.jsons设置有问题 { "workbench.colorTheme": "Default Light", "cmake.pinnedCommands": [ "workbench.action.tasks.configu…...

Java中对消息序列化和反序列化并且加入到Spring消息容器中

--- 参考项目&#xff1a;苍穹外卖。 在对没有Java中的数据序列化时&#xff0c;比如说时间格式&#xff1a; 时间的格式是这种没有格式化的效果&#xff0c;因为在给前端返回数据时&#xff0c;返回的结果并没有序列化。 所以&#xff0c;需要对返回的数据序列化。 首先需…...

FFmpeg源码:av_base64_decode函数分析

一、引言 Base64&#xff08;基底64&#xff09;是一种基于64个可打印字符来表示二进制数据的表示方法。由于log2 646&#xff0c;所以每6个比特为一个单元&#xff0c;对应某个可打印字符。3个字节相当于24个比特&#xff0c;对应于4个Base64单元&#xff0c;即3个字节可由4个…...

【后端面试总结】mysql的group by怎么用

GROUP BY 是 SQL 中的一种用于对结果集进行分组的子句&#xff0c;常与聚合函数&#xff08;如 COUNT()、SUM()、AVG()、MAX() 和 MIN() 等&#xff09;一起使用。GROUP BY 的作用是基于一个或多个列对查询结果进行分组&#xff0c;然后可以对每个分组执行聚合操作。 以下是 G…...

计算机视觉和图像处理

计算机视觉与图像处理的最新进展 随着人工智能技术的飞速发展&#xff0c;计算机视觉和图像处理作为其中的重要分支&#xff0c;正逐步成为推动科技进步和产业升级的关键力量。 一、计算机视觉的最新进展 计算机视觉&#xff0c;作为人工智能的重要分支&#xff0c;主要研究如…...

一文读懂Python之random模块(31)

random模块是Python的内置标准库&#xff0c;用于生成各类随机数&#xff0c;可以用作生成网站初始登录密码和随机验证码。 一、random模块简介 random模块可以生成随机数&#xff0c;包括随机整数、浮点数、随机元素等。 二、random模块相关概念 随机数&#xff1a; 是指在…...

p1044 栈

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

吴恩达深度学习——超参数调试

内容来自https://www.bilibili.com/video/BV1FT4y1E74V&#xff0c;仅为本人学习所用。 文章目录 超参数调试调试选择范围 Batch归一化公式整合 Softmax 超参数调试 调试 目前学习的一些超参数有学习率 α \alpha α&#xff08;最重要&#xff09;、动量梯度下降法 β \bet…...

SQL NOW() 函数详解

SQL NOW() 函数详解 引言 在SQL数据库中&#xff0c;NOW() 函数是一个常用的日期和时间函数&#xff0c;用于获取当前的时间戳。本文将详细介绍 NOW() 函数的用法、参数、返回值以及在实际应用中的注意事项。 函数概述 NOW() 函数返回当前的日期和时间&#xff0c;格式为 Y…...

【JAVA基础】双亲委派

双亲委派可以简单理解为, 当收到加载请求时, 会依次向上加载 ; 只有当父类加载器无法完成加载请求时&#xff0c;子类加载器才会尝试自己去加载。 工作原理 类加载请求传递&#xff1a;当应用程序需要加载一个类时&#xff0c;比如通过ClassLoader.loadClass()方法&#xff0…...

刷题记录 HOT100回溯算法-6:79. 单词搜索

题目&#xff1a;79. 单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻…...

JavaScript系列(52)--编译优化技术详解

JavaScript编译优化技术详解 &#x1f680; 今天&#xff0c;让我们深入探讨JavaScript的编译优化技术。通过理解和应用这些技术&#xff0c;我们可以显著提升JavaScript代码的执行效率。 编译优化基础概念 &#x1f31f; &#x1f4a1; 小知识&#xff1a;JavaScript引擎通常…...

Ollama+DeepSeek本地大模型部署

1、Ollama 官网&#xff1a;https://ollama.com/ Ollama可以干什么&#xff1f; 可以快速在本地部署和管理各种大语言模型&#xff0c;操作命令和dokcer类似。 mac安装ollama&#xff1a; # 安装ollama brew install ollama# 启动ollama服务&#xff08;默认11434端口&#xf…...

在 WSL2 中重启 Ubuntu 实例

在 WSL2 中重启 Ubuntu 实例&#xff0c;可以按照以下步骤操作&#xff1a; 方法 1: 使用 wsl 命令 关闭 Ubuntu 实例: 打开 PowerShell 或命令提示符&#xff0c;运行以下命令&#xff1a; wsl --shutdown这会关闭所有 WSL2 实例。 重新启动 Ubuntu: 再次打开 Ubuntu&#x…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

软件工程 期末复习

瀑布模型&#xff1a;计划 螺旋模型&#xff1a;风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合&#xff1a;模块内部功能紧密 模块之间依赖程度小 高内聚&#xff1a;指的是一个模块内部的功能应该紧密相关。换句话说&#xff0c;一个模块应当只实现单一的功能…...

AD学习(3)

1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分&#xff1a; &#xff08;1&#xff09;PCB焊盘&#xff1a;表层的铜 &#xff0c;top层的铜 &#xff08;2&#xff09;管脚序号&#xff1a;用来关联原理图中的管脚的序号&#xff0c;原理图的序号需要和PCB封装一一…...