在中間件中使用 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

 

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