Reputation: 745
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?
Upvotes: 10
Views: 6167
Reputation: 3677
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
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:
public MyContext (DbContextOptions<MyContext> options) : base(options) { ... }
and now it works right.
Upvotes: 0
Reputation: 64259
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.
Upvotes: 11