C#:在Task中使用依赖注入的Service/EFContext
dotnet core時代,依賴注入基本已經成為標配了,這就不多說了.
前幾天在做某個功能的時候遇到在Task中使用EF DbContext的問題,學藝不精的我被困擾了不短的一段時間,于是有了這個文章.
先說一下代碼結構和場景.
首先有一個HouseDbContext,代碼大概是下面這樣:
public class HouseDbContext : DbContext{ ?? ?public HouseDbContext(DbContextOptions<HouseDbContext> options): base(options) ? ?{} ? ?public DbSet<Notice> Notices { get; set; } }
接著已經在StarUp.cs中初始化并注入了,注入代碼是這樣的:
services.AddDbContextPool<HouseDbContext>(options =>{options.UseLoggerFactory(loggerFactory);options.UseMySql(Configuration["MySQLString"].ToString()); });有一個NoticeService.cs 會用到HouseDbContext 進行增刪查改
當然我們也需要把NoticeService注入到容器中,類似這樣
services.AddScoped<NoticeService,NoticeService>();現在一切都是很美好的,也能正常查詢出Notice
然后某一天來了,有個需求是Update Notice之后需要把Notice同步到另外一個地方,例如Elasticsearch?
代碼如下:
然后一跑...
代碼炸了...
恭喜你獲得跨線程使用EF DbContext導致上下文不同步的異常.
錯誤大概長這樣.
System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. ? ? ?Object name: 'HouseDbContext'.估計現在整個人都不好了.
這個撒意思呢?
無法訪問被釋放的對象。這種錯誤的一個常見原因是使用從依賴注入中解決的上下文,然后在應用程序的其他地方嘗試使用相同的上下文實例。如果您在上下文上調用Dispose(),或者在using語句中包裝上下文,可能會發生這種情況。如果使用依賴項注入,則應該讓依賴項注入容器處理上下文實例。用人話來說是什么意思呢?
這里的HouseDbContext是依賴注入進來的,生命周期由容器本身管理;
在Task.Run中再次使用HouseDbContext實例中由于已經切換了線程了,
HouseDbContext實例已經被釋放掉了,無法再繼續使用同一個實例,我們應該自己初始化HouseDbContext來用.
到這里的話,上次我做的時候心生一計:
既然我們不能直接從構造函數注入的HouseDbContext實例的話,我們是不是可以直接從依賴注入容器中拿一個實例回來呢?
那在dotnet core里面可以用個什么從容器中取出實例呢?
答案是:IServiceProvider
代碼如下:
跑一下看看...
然而事實告訴我,實例是能拿得到,然而還是會炸,錯誤是一樣的.
原因其實還是一樣的,這里已經不受依賴注入托管了,人家的上下文你別想用了.
那咋辦呢...
在EF6,還可以直接new HouseDbContext 一個字符串進去初始化,在EF Core這里,已經不能這樣玩了.
那可咋辦呢?
翻了好多資料都沒看到有人介紹過咋辦,最后居然還是在官網教程里面找到了樣例.
先看代碼...
教程代碼在:Configuring a DbContext:?https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext?
大功告成...
原文地址:https://www.cnblogs.com/liguobao/p/9992451.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的C#:在Task中使用依赖注入的Service/EFContext的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软Cloud+AI本地化社区贡献指南
- 下一篇: DevOps/.NET 微服务 秋季分享