在中间件中使用 Scoped 模式服务

作用域(Scoped)服务和瞬时(Transient)服务都与请求的生命周期相关,但它们之间有一些区别。

1. 作用域(Scoped)服务:
- 作用域服务的生命周期与每个请求的生命周期相对应。也就是说,每个请求都会创建一个作用域服务的实例,并且在请求处理过程结束时该实例将被释放。
- 作用域服务在同一个请求中是共享的,但在不同请求之间是隔离的。也就是说,每个请求都会获得一个独立的作用域服务实例,不同请求之间的作用域服务实例是相互独立的。
- 作用域服务适合在请求处理过程中需要保持状态或跟踪请求特定数据的情况。

2. 瞬时(Transient)服务:
- 瞬时服务的生命周期是短暂的,每次使用时都会创建一个新的实例。
- 瞬时服务在每次请求中都会创建一个新的实例,不会共享实例。
- 瞬时服务适合那些不需要保持状态或跟踪请求特定数据的情况,每次使用时都需要一个新的实例。

总的来说,作用域服务和瞬时服务都与请求的生命周期相关,但作用域服务在同一个请求中是共享的,而瞬时服务在每次使用时都会创建一个新的实例。

在ASP.NET Core中,您可以使用`AddScoped`方法将服务注册为作用域服务,使用`AddTransient`方法将服务注册为瞬时服务。

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);
        }
    }
View Code

注入:

app.UseMiddleware<TestMiddleware>();//添加中间件
View Code

 

方法二:使用继承 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);
}
}
View Code

注入:

//添加中间件
builder.Services.AddTransient<TestMiddleware>();
app.UseMiddleware<TestMiddleware>();
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章