使用ApplicationDbContext和来自appsettings.json的

时间:2017-07-04 01:57:11

标签: c# dependency-injection asp.net-core entity-framework-core

我正在尝试从ApplicationDbContext类中抽象出任何连接信息,以便我可以利用不同的数据库进行开发,登台,生产。我首先注册Startup.cs中的服务

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过程中缺少一些内容,我们将不胜感激任何建议或意见。

1 个答案:

答案 0 :(得分: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);
    }
}