I have a problem with using specific service depend on other service in web api Program file. I create IDatabaseOption interface and DatabaseOptions class like this (and add values in appsettings):
public interface IDatabaseOptions
{
string ConnectionString { get; set; }
DatabaseType DatabaseType { get; set; }
string DatabaseName { get; set; }
}
public class DatabaseOptions : IDatabaseOptions
{
public string ConnectionString { get; set; }
public DatabaseType DatabaseType { get; set; }
public string DatabaseName { get; set; }
}
and the registration is:
services.Configure<DatabaseOptions>(configuration.GetSection(nameof(DatabaseOptions)));
services.AddSingleton<IDatabaseOptions>(serviceProvider => serviceProvider.GetRequiredService<IOptions<DatabaseOptions>>().Value);
And next step I'd like to register concrete DbContext based on DatabaseType like this:
services.AddDbContext<ApplicationDbContext>().AddOptions<DbContextOptionsBuilder>().Configure<IDatabaseOptions>((options, databaseOptions) =>
{
switch (databaseOptions.DatabaseType)
{
case DatabaseType.MSSQL:
options.UseSqlServer(databaseOptions.ConnectionString);
break;
case DatabaseType.POSTGRESQL:
options.UseNpgsql(databaseOptions.ConnectionString);
break;
default: break;
}
});
and at this point it not work. If I use DI in for example Repository in constructor like Repository(ApplicationDbContext), the context is not set. I don't have to use BuildServiceProvider() because it is not proper solution. How can I use registered service to decide for other service at this point?
CodePudding user response:
If you make the settings while registering the DbContext object, the problem will disappear. When I tried the following piece of code, the error you mentioned disappeared.
services.AddDbContext<ApplicationDbContext>((provider, optionsBuilder) =>
{
var options = provider.GetRequiredService<IDatabaseOptions>();
switch (options.DatabaseType)
{
case DatabaseType.MSSQL:
optionsBuilder.UseSqlServer(options.ConnectionString);
break;
case DatabaseType.POSTGRESQL:
break;
default:
throw new ArgumentOutOfRangeException();
}
});