I'm new to .net core and I have a problem with using multiple configuration providers for a single POCO. I'm using .net core, not asp.net core.
I tried to simplify the classes for clarity, please ignore any compilation errors. The model for my configuration is as follows:
public class Configurations
{
public EnvironmentConfig EnvironmentConfig {get; set;}
public ServerConfig ServerConfig {get; set;}
}
public class EnvironmentConfig
{
public string EnvironmentStr {get; set;}
}
public class ServerConfig
{
public string Address {get; set;}
public string Username {get; set;}
public string Password {get; set;}
}
I have two providers - appsettings.json and a database. The database is used with other services, so it's not possible to alter the data easily (it can be considered read-only). The appsettings.json file has the following hierarchy:
{
"EnvironmentConfig": {
"EnvironmentStr": "dev"
},
"ServerConfig": {
"Address": "https://example.com"
// the other properties are not here, they're kept only in the database
}
}
The database doesn't have hierarchy and provides only the missing properties (I'll use JSON again for consistency):
{
"Username": "user"
"Password": "password"
}
When I try to get a IOptionsMonitor<Configurations> object, only the Address property is populated inside ServerConfig, like it's only reading from appsettings.json (username and password are at the root level, so it's not binding them correctly):
var configs = host.Services.GetService<IOptionsMonitor<Configurations>>().CurrentValue;
{
"EnvironmentConfig": {
"EnvironmentStr": "dev"
},
"ServerConfig": {
"Address": "https://example.com"
"Username": null,
"Password": null
}
}
And when I try to get a IOptionsMonitor<ServerConfig> object, it binds only the data from the database:
var serverConfig = host.Services.GetService<IOptionsMonitor<ServerConfig>>().CurrentValue;
{
"Address": null,
"Username": "user",
"Password": "password"
}
It looks like I'm not binding it correctly. I tried multiple ways, but it didn't work:
public static IServiceCollection AddConfiguration(this IServiceCollection services, IConfiguration configuration)
{
services
.Configure<ServerConfig>(configuration) // the db properties are also at root level
.Configure<Configurations>(configuration);
return serviceCollection;
}
public static IServiceCollection AddConfiguration(this IServiceCollection services, IConfiguration configuration)
{
services
.AddOptions<ServerConfig>()
.Bind(configuration.GetSection("ServerConfig");
services
.AddOptions<Configurations>()
.Bind(configuration);
return serviceCollection;
}
Could someone explain how to bind it correctly, regardless of the difference in hierarchy, so ServerConfig has all properties populated when inside Configurations?