是的,DbContext
的默認生存時間是有作用域的。這是打算這樣。
實例化DbContext
非常便宜,它確保您不會使用很多資源。如果你有一個單身生命週期的DbContext
,那麼你所讀取的所有記錄將被DbContext
跟蹤,除非你明確禁用了跟蹤。這將需要更多的內存使用,並且會不斷增長。
並且越是DbContext
音軌,性能將越低。這就是爲什麼你經常看到DbContext
只用於using(var context = new AppDbContext())
塊。
但是,在web應用程序中,使用using
塊是不好的,因爲生命週期由framework管理,如果將它置於提前調用之後,將會失敗併產生異常。
如果您在另一端使用瞬態生命週期,您將失去「事務」功能。在範圍內,DbContext
具有與請求一樣長的事務範圍。
如果您需要更細粒度的控制,您必須使用工作單元模式(其中DbContext
已經使用)。
關於第二個問題:
如果你創建一個服務,它必須有一個生命週期這等於範圍的一個或較短(讀:作用域或瞬態)。
如果您明確需要延長服務的使用壽命,則應該將DbContext
工廠服務或工廠方法注入到服務中。
你可以像
services.AddTransient<Func<AppDbContext>>((provider) => new Func<MyDbContext>(() => new AppDbContext()));
services.AddSingleton<IMySingletonService, MySingletonService>();
做到這一點,您的服務可能是這樣的:
public class MySingletonService : IMySingletonService, IDisposable
{
private readonly AppDbContext context;
public MySingletonService(Func<AppDbContext> contextFactory)
{
if(contextFactory == null)
throw new ArgumentNullException(nameof(contextFactory));
// it creates an transient factory, make sure to dispose it in `Dispose()` method.
// Since it's member of the MySingletonService, it's lifetime
// is effectively bound to it.
context = contextFactory();
}
}
這是真的,其管理生命週期控制器?或者是在請求結束時處理每個請求的作用域的DI?我想了解更好的 –
我的不好。我打算說框架。有一個控制器工廠('IControllerFactory',見https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/Controllers/DefaultControllerFactory.cs默認實現)在它的'CreateController '創建控制器並將其部署並放置的方法,它是'ReleaseController()'方法中的依賴關係。另請參閱此GitHub問題的內部工作的更多細節,以及它爲什麼這樣工作:https://github.com/aspnet/Mvc/issues/3727 – Tseng
謝謝。如果我有一個在其構造函數中使用DbContext的存儲庫,並且它實現了IDisposable,它應該從它自己的dispose方法調用DbContext上的dispose?我注意到用於Identity的EF UserStore不會在dbcontext上調用dispose,但我感覺不對,因此我試圖理解它們爲什麼不會這樣做。 –