1

I am trying to inject a simple connection string in an ASP.NET Core 2.1 API project.

appsettings.json:

{
    "ConnectionStrings": {
        "DefaultConnection": "Server=xxx.database.windows.net;Database=xxx;User Id=frontend;Password=xxx;"
    }
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    var connStr = Configuration.GetConnectionString("DefaultConnection");
    services.AddDbContext<DB>(options => options.UseSqlServer(connStr));

DbContext:

public class DB : DbContext
{
    public DB(DbContextOptions<DbContext> options) : base(options) { }
    public DB() { }

    public DbSet<MenuItem> MenuItemList { get; set; }
}

My Controller:

public class MenuItemsController : ControllerBase
{
    DB _context;
    public MenuItemsController(DB context)
    {
        _context = context;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        try
        {
            var ddd = _context.MenuItemList.ToList();
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return new string[] { "value1", "value2" };
    }
}

I get following error:

No database provider has been configured for this DbContext.

The connection string is read correctly from the appsettings file, am I missing something? I have read other posts where people just configure the connection part in the DB context but I would prefer to do it this way with injection.

0

2 Answers 2

3

Your constructor accepting a DbContextOptions is wrong. You need one that accepts one for your specific DbContext. So instead of:

public DB(DbContextOptions<DbContext> options) : base(options) { }

Use:

public DB(DbContextOptions<DB> options) : base(options) { }
Sign up to request clarification or add additional context in comments.

2 Comments

Your totally right, thanks. Your two guys with same answer dont know how to mark both as answered.
No problem, poke gives a better explanation of what went wrong.
1

These are the two constructors on your database context type DB:

public DB(DbContextOptions<DbContext> options) : base(options) { }
public DB() { }

So when the dependency injection container is attempting to resolve the database context, it looks at those constructors and tries to determine which constructor to use the create the object.

First, it will look at the one expecting a DbContextOptions<DbContext> argument. Usually, the DbContextOptions are automatically registered as part of the AddDbContext<T>() call. However, the types that are registered are DbContextOptions (non-generic) and DbContextOptions<T>.

So in your case, for a database context DB, only the types DbContextOptions and DbContextOptions<DB> are registered.

So the dependency injection container is not able to resolve DbContextOptions<DbContext> and as such cannot use that constructor. So it will use the next constructor which happens to be the empty constructor. Since the empty constructor does not support any configuration, the database context will be unconfigured and you will receive that error when attempting to use it.

The solution is pretty simple: Adjust the DbContextOptions<> type in that constructor. You can either use DbContextOptions or DbContextOptions<DB>. The latter is generally preferred since it allows you to have multiple database contexts in the same application but if you just have one, then you can also just use the former. I would also recommend you to remove the empty constructor to make sure that it won’t be used accidentally:

public DB(DbContextOptions<DB> options)
    : base(options)
{ }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.