我在Azure Service Fabric中有一個無狀態服務,並且使用了Microsoft.Extensions.DependencyInjection,但是對於其他任何DI框架都存在同樣的問題。在我的Program.cs中,我創建了一個ServiceCollection,添加了所有(但是一個)我的註冊,創建服務提供者並將其傳遞給我的服務的構造函數。任何具有外部入口的服務方法將創建一個新的服務範圍並調用主要的業務邏輯類。問題在於我想要具有作用域生命週期的其中一個類需要一個值,該值是請求本身的輸入參數。這是我想要實現的代碼片段。在範圍內配置/註冊depressive注入範圍服務
internal sealed class MyService : StatelessService, IMyService
{
private IServiceProvider _serviceProvider;
private IServiceScopeFactory _scopeFactory;
public MyService(StatelessServiceContext context, IServiceProvider serviceProvider)
: base(context)
{
_serviceProvider = serviceProvider;
_scopeFactory = _serviceProvider.GetRequiredService<IServiceScopeFactory>();
}
public async Task<MyResponse> ProcessAsync(MyRequest request, string correlationId, CancellationToken cancellationToken)
{
using (var scope = _scopeFactory.CreateScope())
{
var requestContext = new RequestContext(correlationId);
//IServiceCollection serviceCollection = ??;
//serviceCollection.AddScoped<RequestContext>(di => requestContext);
var businessLogic = scope.ServiceProvider.GetRequiredService<BusinessLogic>();
return await businessLogic.ProcessAsync(request, cancellationToken);
}
}
}
取消令牌已經過去到處,包括不直接使用它,所以它可以傳遞給那些使用它的依賴類,我想避免這樣做,與同一請求上下文。
我的MVC API中存在同樣的問題。我可以創建一箇中間件,它將從HTTP標頭中提取相關標識,所以API控制器不需要像我的服務結構服務那樣處理它。我可以使它工作的一種方法是給RequestContext
一個默認的構造函數,並有一個可變的相關ID。但是,在請求期間關聯ID沒有被改變是絕對關鍵的,所以我真的很喜歡在上下文類中擁有隻獲取屬性的安全性。
我現在最好的想法是擁有一個有SetCorrelationId方法的作用域RequestContextFactory,而RequestContext註冊只是簡單地調用工廠來獲取一個實例。如果在設置id之前請求一個新實例,工廠可以拋出一個異常,以確保不會創建無id的上下文,但它不是一個好的解決方案。
如何使用依賴注入框架清理註冊只讀對象,其中值取決於傳入請求?