3

我想從我的ApplicationDbContext類抽象任何連接信息,以便我可以利用不同的數據庫進行開發,分段,生產。我開始從Startup.cs註冊服務從appsettings.json使用ApplicationDbContext和DI

services.AddDbContext<ApplicationDbContext>(options => 
     options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

我ApplicationDbContext類:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) 
    : base(options) 
    { 
    } 

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 
    } 
} 

運行此應用程序,我得到以下錯誤:

出現InvalidOperationException:無法創建類型爲「SquadApps.Data.ApplicationDbContext」的實例。模型綁定的複雜類型不能是抽象或值類型,並且必須具有無參數的構造函數。

所以很自然我嘗試添加一個參數的構造函數

public ApplicationDbContext() { } 

現在得到另一個錯誤:

出現InvalidOperationException:沒有數據庫提供商已經配置了這個的DbContext。可以通過重寫DbContext.OnConfiguring方法或使用應用程序服務提供者上的AddDbContext來配置提供程序。如果使用AddDbContext,則還要確保您的DbContext類型在其構造函數中接受DbContextOptions對象,並將其傳遞給DbContext的基礎構造函數。

如果我回到具有存儲在ApplicationDbContext類,像這樣的連接字符串:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
{ 
    optionsBuilder.UseSqlServer("........"); 
} 

然後一切工作正常,但顯然這不是理想的,可能是一個壞的做法。我認爲我缺少有關DI流程的任何建議或建議,不勝感激。

+0

有您註冊的身份在啓動依賴? services.AddIdentity () .AddEntityFrameworkStores () .AddDefaultTokenProviders(); – DSR

+0

完全按照書面。這是註冊後直接services.AddDbContext – defect833

+0

我創建了一個新的WebApplication與個人用戶帳戶使用模板。它創建了與您的相同的代碼,但仍然有效。你能否提供實際證明你所看到的錯誤的代碼? – Smit

回答

1

解決方案原來是我如何試圖打電話給DI。我錯誤地認爲DI可以在我的控制器內部每個IActionResult被調用,但實際上它必須發生在控制器的構造函數內。這使得DI可用於控制器內的所有IActionResult方法。工作DI通話

例子:

public class HomeController : Controller 
{ 
    private readonly ApplicationDbContext _ctx; 
    private readonly CompanySettings _companySettings; 

    public HomeController(ApplicationDbContext ctx, IOptions<CompanySettings> settings) 
    { 
     _ctx = ctx; 
     _companySettings = settings.Value; 
    } 

    public IActionResult Index() 
    { 
     var model = new HomeViewModel(); 

     // _ctx and _companySettings can be used here 

     return View(model); 
    } 
} 
+1

完全救了我的一天!謝謝! – Defkon1

+1

實際上,您可以使用操作方法中的DI。你沒有意識到你需要在這種情況下采取不同的做法,用「FromServices」屬性來修飾每個「DI」參數。 E.g.這將起作用:'public IActionResult Index([FromServices] ApplicationDbContext ctx,[FromServices] IOptions settings)'。但是這會導致你看到的異常:'public IActionResult Index(ApplicationDbContext ctx,IOptions settings)' – Granger