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

devtools/2025/2/3 15:32:54/

目录

一、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>();});
}


http://www.ppmy.cn/devtools/155755.html

相关文章

14 2D矩形模块( rect.rs)

一、 rect.rs源码 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENS…

TypeScript语言的语法糖

TypeScript语言的语法糖 TypeScript作为一种由微软开发的开源编程语言&#xff0c;它在JavaScript的基础上添加了一些强类型的特性&#xff0c;使得开发者能够更好地进行大型应用程序的构建和维护。在TypeScript中&#xff0c;不仅包含了静态类型、接口、枚举等强大的特性&…

计算机毕业设计Python动漫推荐系统 漫画推荐系统 动漫视频推荐系统 机器学习 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

vim的多文件操作

[rootxxx ~]# vim aa.txt bb.txt cc.txt #多文件操作 next #下一个文件 prev #上一个文件 first #第一个文件 last #最后一个文件 快捷键: ctrlshift^ #当前和上个之间切换 说明&#xff1a;快捷键ctrlshift^&#xff0c…

书生大模型实战营7

文章目录 L1——基础岛提示词工程实践什么是Prompt(提示词)什么是提示工程提示设计框架CRISPECO-STAR LangGPT结构化提示词LangGPT结构编写技巧构建全局思维链保持上下文语义一致性有机结合其他 Prompt 技巧 常用的提示词模块 浦语提示词工程实践(LangGPT版)自动化生成LangGPT提…

计算机网络网络层进阶:NAT、ARP 与 IP 系列技术全析!!!

一、网络地址转换NAT 私有IP 地址(内网IP)&#xff1a; 10.0.0.0~10.255.255.255 172.16.0.0~172.31.255.255 192.168.0.0~192.168.255.255 只允许分配给局域网内部的节点,不允许分配给互联网上的节点每个局域网内部都可以自行分配这些私有 IP 地址私有 IP 地址是可复用的&…

oracle: 多表查询之联合查询[交集intersect, 并集union,差集minus]

把多个查询结果上下合并, 即, 通过操作符将多个 SELECT 语句的结果集合并为一个结果集。虽然联合查询通常用于从多个表中检索数据&#xff0c;但它也可以用于从同一个表中检索不同的数据集。 联合查询: 交集,并集,差集 默认的排序规则通常是基于查询结果集中的列的自然顺序。…

Games202Lecture 6 Real-time Environment Mapping

RTRT RTRT&#xff08;real time ray tracing): path tracingdenoising PRT PRT (Precomputed radiance transfer):离线预计算&#xff0c;运行时快速内积。 预计算&#xff08;Offline Precomputation&#xff09;&#xff1a; 传输函数&#xff08;Transfer Function&…