Normally, we would have some model
public class ConnectionStrings
{
public string Sql { get; set; }
public string NoSql { get; set; }
}
then we have something in appsettings.json
as follow:
"ConnectionStrings": {
"Sql": "some connection string",
"NoSql": "some other connection string"
}
Then I bind the model as follows:
services.Configure<ConnectionStrings>(
options => Configuration.GetSection("ConnectionStrings").Bind(options));
All works perfectly, but it doesn't make sense for my model to be mutable since it is holding important information. After all, configurations are static information, so once my model is read, it should stay like it is.
Is there any other way of doing this more safely?
Used to build key/value-based configuration settings for use in an application.
IOptions is singleton and hence can be used to read configuration data within any service lifetime. Being singleton, it cannot read changes to the configuration data after the app has started. Run the app and hit the controller action. You should be able to see the values being fetched from the configuration file.
IOptionsMonitor is a Singleton service that retrieves current option values at any time, which is especially useful in singleton dependencies.
Bind(IConfiguration, String, Object)Attempts to bind the given object instance to the configuration section specified by the key by matching property names against configuration keys recursively.
As an alternative, for version 2.1+, you can now bind to non-public properties by specifying to do so with BinderOptions
:
services.Configure<ConnectionStrings>(options =>
Configuration.GetSection("ConnectionStrings")
.Bind(options, c => c.BindNonPublicProperties = true));
or to just get them:
var connectionStrings = Configuration.GetSection("ConnectionStrings")
.Get<ConnectionStrings>(c => c.BindNonPublicProperties = true);
code like this uses underhood the ConfigurationBinder
that expects public properties. From BindProperty method:
// We don't support set only, non public, or indexer properties
if (property.GetMethod == null ||
!property.GetMethod.IsPublic ||
property.GetMethod.GetParameters().Length > 0)
{
return;
}
As a workaround, I may suggest populating your class manually. Take the following as an example:
public class ConnectionStrings
{
public ConnectionStrings(string sql, string noSql)
{
Sql = sql;
NoSql = noSql;
}
public string Sql { get; private set; }
public string NoSql { get; private set; }
}
and then in ConfigureServices
method:
var sqlValue = Configuration.GetValue<string>("ConnectionStrings:Sql", string.Empty);
var noSqlValue = Configuration.GetValue<string>("ConnectionStringsApp:NoSql", string.Empty);
services.Configure<ConnectionStrings>(
options => new ConnectionStrings(sqlValue, noSqlValue));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With