Closed chrisbbe closed 4 years ago
Hi @chrisbbe,
EfCore.GenericServices is designed to work with Dependency Injection (DI). Therefore the DbContext provided by the DI. That's why I have extension methods such as ConfigureGenericServicesEntities
to register your DTOs and the CrudServices
and CrudServicesAsync
services. ASP.NET Core is built around DI.
You have two options.
CrudServices
and CrudServicesAsync
classes. That's what I do for unit testing - see this link on how I do that with unit tests. The same approach would work in a non-DI system (I know one person who did that).Thanks for the feedback.
All of this is clear to me. The reason I ask is that registering my DbContext with the GenericServices causes the DbContext constructor and OnConfigure(...) method to be executed during startup (before any user requests are hitting ASP.Net Core). While removing the GenericServices DI registration does not cause the DbContext to be executed. The issue here is that the ITenantProvider injected into the DbContext is used to determine the connection string based on the authenticated user, leading to an empty connection string, which makes EF Core throw an exception.
Is the DbContext expected to be executed during initialization?
Code example:
public class TenantDbContext : DbContext
{
private readonly Tenant _tenant;
public TenantDbContext(DbContextOptions<TenantDbContext> options, ITenantProvider tenantProvider) : base(options)
{
_tenant = tenantProvider.GetTenant();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseNpgsql(_tenant.DatabaseConnectionString);
base.OnConfiguring(optionsBuilder);
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TenantDbContext>();
services.GenericServicesSimpleSetup<TenantDbContext>(Assembly.GetAssembly(typeof(TenantDto)));
}
}
hi @chrisbbe,
Yes, GenericServices has to scan the entities in the DbContext to link the DTOs to the entities. There is no way around that. But GenericServices doesn't query the database.
Not sure there is a solution - maybe a default, empty database?? Or maybe a valid database connection but no database on the other end? As I said, there is a the new EF Core 5 feature about changing the connection that might help.
PS. I needed to research the new EF Core 5 feature about changing the connection string for chapter 11 in my book Entity Framework Core in Action, second edition. There is no documentation but a looking at the commit related to this feaure it does look useful.
The comments in the code state that the connection string has to be non-null before you access the database, and I see other changes which allows connection string to be null before hand (I think!). It also offers a SetConnectionString
method to set/change the connection string any time (a connection mustn't be open).
I won't be playing with this new feature for a week or so, but it does sound like the right way to handle the issue you have irrespective of using GenericServices.
Hi,
Why is the DbContext initialized during configuration of the service? This makes it hard to use GenericServices for DbContexts which overrides the
void OnConfigure(DbContextBuilder optionsBuilder)
method in situations where the DbContext is configured dynamically, ex. where the connection string is determined based on the UserClaims during an request.Thanks