目录
一、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
app
是 IApplicationBuilder
类型的对象,它用于配置请求处理管道。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.cs
或 Startup.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.cs
或 Program.cs
中,我们需要将服务注册到 DI 容器中。通常,这些注册是在 ConfigureServices
方法中进行的。
public class Startup
{public void ConfigureServices(IServiceCollection services){// 注册 IMYService 接口及其实现类 MyServiceservices.AddSingleton<IMyService, MyService>();}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){// 省略其他中间件配置...}
}
3. 使用依赖注入获取并执行服务
假设我们在 Controller
或 Middleware
中需要执行 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>();});
}