在中间件中使用 Scoped 模式服务
作用域(Scoped)服务和瞬时(Transient)服务都与请求的生命周期相关,但它们之间有一些区别。
1. 作用域(Scoped)服务:
- 作用域服务的生命周期与每个请求的生命周期相对应。也就是说,每个请求都会创建一个作用域服务的实例,并且在请求处理过程结束时该实例将被释放。
- 作用域服务在同一个请求中是共享的,但在不同请求之间是隔离的。也就是说,每个请求都会获得一个独立的作用域服务实例,不同请求之间的作用域服务实例是相互独立的。
- 作用域服务适合在请求处理过程中需要保持状态或跟踪请求特定数据的情况。
2. 瞬时(Transient)服务:
- 瞬时服务的生命周期是短暂的,每次使用时都会创建一个新的实例。
- 瞬时服务在每次请求中都会创建一个新的实例,不会共享实例。
- 瞬时服务适合那些不需要保持状态或跟踪请求特定数据的情况,每次使用时都需要一个新的实例。
总的来说,作用域服务和瞬时服务都与请求的生命周期相关,但作用域服务在同一个请求中是共享的,而瞬时服务在每次使用时都会创建一个新的实例。
在ASP.NET Core中,您可以使用`AddScoped`方法将服务注册为作用域服务,使用`AddTransient`方法将服务注册为瞬时服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | app.Run(async (context) => { // 获取作用域服务 var scopedService1 = context.RequestServices.GetService<ScopedService>(); var scopedService2 = context.RequestServices.GetService<ScopedService>(); // 获取瞬时服务 var transientService1 = context.RequestServices.GetService<TransientService>(); var transientService2 = context.RequestServices.GetService<TransientService>(); // 打印服务实例的 ID await context.Response.WriteAsync($ "Scoped Service 1: {scopedService1.Id}\n" ); await context.Response.WriteAsync($ "Scoped Service 2: {scopedService2.Id}\n" ); await context.Response.WriteAsync($ "Transient Service 1: {transientService1.Id}\n" ); await context.Response.WriteAsync($ "Transient Service 2: {transientService2.Id}\n" ); }); |
方法一:使用IServiceProvider创建Scope重新获得新的Service

public class TestMiddleware { private readonly RequestDelegate _next; private readonly IServiceProvider _serviceProvider; public TestMiddleware(RequestDelegate next, IServiceProvider serviceProvider) { _next = next; _serviceProvider = serviceProvider; } public async Task InvokeAsync(HttpContext context) { _serviceProvider.CreateScope().ServiceProvider?.GetService<ITestService>()?.GetTest(); Console.WriteLine(context.Connection?.RemoteIpAddress?.ToString()); await _next.Invoke(context); } }
注入:

app.UseMiddleware<TestMiddleware>();//添加中间件
方法二:使用继承 IMiddleware接口方法

public class TestMiddleware : IMiddleware { private readonly ITestService _testService; public TestMiddleware(ITestService testService) { _testService = testService; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { _testService.Test(); Console.WriteLine(context.Connection?.RemoteIpAddress?.ToString()); await next(context); } }
注入:

//添加中间件 builder.Services.AddTransient<TestMiddleware>(); app.UseMiddleware<TestMiddleware>();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2016-12-06 闭包的使用