Resolve DBContext with implements another interface in Asp.Net Core

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

Question

I have an EF Context that has it's signature

public class MyContext : DbContext, IDbContext
{

}

When I add it to services, I use it

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

But it's causing problems when I'm injecting the IDbContext, like this

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

Because it's duplicating my DbContext, and It should be only one per request.

How can I resolve it?

1
6
10/24/2016 9:14:44 PM

Accepted Answer

In your case using the factory method should work fine.

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

This way you will resolve a new instance of MyDbContext (on first call) or return the already instantiated instance of it during a request on conclusive calls.

8
10/25/2016 5:58:11 AM

Popular Answer

Please note, that if you are registering multiple different DbContexts, you will have to correctly define the constructors using the correct specific DbContextOptions. If you don't you run the risk of having the incorrect type being resolved by the DI.

For example, I was using an MyContext : DbContext, IDbContext, similar to OP, but I was also using a generic DbContext for temporary storage for OpenIddict:

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

Crucially, my MyContext constructor was too generic - created using a Visual Studio Quick Action template :( ugh

Wrong:

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

This results in the DI resolving the wrong DbContext at runtime:

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

At some point I got an error which complained that I didn't have the right type of constructor for my context, so I changed the constructor to:

Correct:

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

and now it works right.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow