使用在Asp.Net Core中實現另一個接口來解析DBContext

asp.net-core c# entity-framework-core

我有一個具有它簽名的EF上下文

public class MyContext : DbContext, IDbContext
{

}

當我將它添加到服務時,我使用它

services.AddDbContext<MyContext>(op =>
{
    op.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
});

但是當我注入IDbContext時,它會導致問題,就像這樣

services.AddScoped(typeof(IDbContext), typeof(MyContext));

因為它複製了我的DbContext,而且每個請求應該只有一個。

我該如何解決?

一般承認的答案

在你的情況下使用工廠方法應該工作正常。

services.AddScoped<IDbContext>(provider => provider.GetService(typeof(MyContext)));

這樣您就可以解析MyDbContext的新實例(在第一次調用時),或者在最終調用請求期間返回已經實例化的實例。


熱門答案

請注意,如果要註冊多個不同的DbContexts,則必須使用正確的特定DbContextOptions正確定義構造函數。如果不這樣做,則存在由DI解決錯誤類型的風險。

例如,我使用的是MyContext : DbContext, IDbContext ,類似於OP,但我也使用通用的DbContext進行DbContext的臨時存儲:

services.AddDbContext<DbContext>(o =>
            {
                o.UseInMemoryDatabase(nameof(DbContext)); //tokens and stuff is stored in memory, not the actual users or passwords. 
                o.UseOpenIddict();
            });

至關重要的是,我的MyContext構造函數過於通用 - 使用Visual Studio Quick Action模板創建:(呃

錯誤:

public MyContext (DbContextOptions options) : base(options) { ... } 

這導致DI在運行時解析錯誤的DbContext:

Microsoft.EntityFrameworkCore.Infrastructure:Information: Entity Framework Core 2.1.4-rtm-31024 initialized 'MyContext' using provider 'Microsoft.EntityFrameworkCore.InMemory' with options: StoreName=DbContext

在某些時候我得到一個錯誤,抱怨我的上下文沒有正確類型的構造函數,所以我將構造函數更改為:

正確:

public MyContext (DbContextOptions<MyContext> options) : base(options) { ... } 

現在它的工作正常。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow