[英]ASP.NET Core - Repository dependency injection fails on Singleton injection
我正在使用SoapCore為ASP.NET Core MVC應用程序創建Web服務。
我正在使用Entity Framework Core和簡單的存儲庫模式來獲取我的數據庫數據。
我通過Startup.cs中的.AddSingleton()
注入存儲庫類:
services.AddSingleton<IImportRepository, ImportRepository>();
services.AddSingleton<IWebService, WebService>();
由於EF DbContext
具有作用域,因此在調用Web服務時出現錯誤:
無法使用單例“ App._Repository.IImportRepository”中的作用域服務“ App.Data.ApplicationDbContext”。
當我改用.AddScoped()
,它可以正常工作。
我讀過通過controllers / classes構造函數注入作用域的依賴關系是不好的做法,因為它“回退”為單例或行為類似。
我想知道是否有另一種方法可以使它與單例一起使用,或者通過ctor在我的控制器中使用作用域注入時,從長遠來看是否會有一些重大缺點(大約100-200個用戶將使用該站點)?
簡而言之,您的終生應該受到“限制”。 僅在有充分理由的情況下才應使用單例或瞬態壽命。 對於單例來說,諸如管理鎖或保存數據等在應用程序的整個生命周期中都需要持續存在的東西,都不適用於存儲庫的概念。 儲存庫應該完全是一次性的。 關鍵是要保留到數據庫或其他存儲中,因此它們不應自行包含任何需要保留的數據。
總之,最好的選擇是使存儲庫范圍有限,以便您可以直接插入上下文。 就構造函數注入而言,我不確定這是一個不好的做法。 實際上,在大多數情況下這就是依賴注入的工作原理,因此您不能一無所有。
如果您絕對需要單身人士,那么唯一的選擇就是服務定位器反模式。 為此,您將注入IServiceProvider
:
public class MyRepo
{
private readonly IServiceProvider _serviceProvider;
public MyRepo(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
...
}
然后, 每當需要上下文時 (這很重要),就需要執行以下操作:
using (var scope = _serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyContext>();
// do something with context
}
作用域對象不能注入到單例對象中。 如此簡單,單例僅在應用程序啟動時創建一次,並被所有后續請求使用。 范圍對象在每個請求期間創建,並在請求結束時處理。 因此,先前創建的單個對象無法知道在每個請求期間創建的作用域對象。 因此,不可能在單例中使用范圍對象。 但是反之亦然。
通過控制器/類構造器注入作用域依賴
我認為這不是一個壞習慣。 如果不是,您打算如何進行單元測試?
同樣,使數據庫上下文單例也是不正確的。 您將同時面臨現金問題/數據異常以及后續要求。 在我看來,必須確定數據庫上下文的范圍,並且必須將使用db-context的所有對象一直確定范圍。
因此,在所有情況下,使所有對象ImportRepository,WebService和DB Context都具有作用域。
干杯,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.