This is a follow-on from a question I asked the other day. I have an AppDbContext
, that extends the DbContext
class, and is used in most projects in my solution. I want to add a BlazorAppDbContext
class (that extends AppDbContext
) to my Blazor server-side project, and add in some Blazor-specific code. My problem was working out how to configure the options to be passed in.
Kudos to Neil W, who walked me through this. I ended up with the following in Program.cs
...
DbContextOptionsBuilder<AppDbContext> b = new();
b.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
b.EnableSensitiveDataLogging();
b.EnableDetailedErrors();
builder.Services.AddTransient(sp =>
new BlazorAppDbContext(b.Options, sp.GetService<AuthenticationStateProvider>()));
That works fine for when I'm doing plain injection, ie decorating a property with the [Inject]
attribute. However, it doesn't help me when I want to use a factory to create the context. See this Microsoft article for why I want to do this).
The code for injecting a regular AppDbContext
factory looked like this...
builder.Services.AddDbContextFactory<AppDbContext>(lifetime: ServiceLifetime.Scoped);
However, substituting BlazorAppDbContext
instead suffers from the same problem that motivated my previous question, namely that I get "System.AggregateException: 'Some services are not able to be constructed" when it tries to create the service.
I thought of trying to mimic the code Neil W showed me, but couldn't work out what to create. When we inject a factory, we ask for an object of type IDbContextFactory<MyDbContext>
, so I tried that...
DbContextOptionsBuilder<AppDbContext> b = new();
b.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
b.EnableSensitiveDataLogging();
b.EnableDetailedErrors();
builder.Services.AddTransient(sp => new BlazorAppDbContext(b.Options, sp.GetService<AuthenticationStateProvider>(), sp.GetService<IHttpContextAccessor>()));
builder.Services
.AddTransient<IDbContextFactory<BlazorAppDbContext>>(sp
=> new DbContextFactory<BlazorAppDbContext>(sp,
b.Options,
new DbContextFactorySource<BlazorAppDbContext>()));
...where b
is the DbContextOptionsBuilder
that Neil W mentioned, extracted into a separate variable so I can use it in both cases.
However, this gave me a compiler error... "Argument 2: cannot convert from 'Microsoft.EntityFrameworkCore.DbContextOptions<
AppDbContext>
' to 'Microsoft.EntityFrameworkCore.DbContextOptions<
BlazorAppDbContext>
'".
Anyone any idea how I do this? Thanks