As with others, I disagree with injecting IOptions into every service that may need it, and looked for other options. My goal was to inject the values needed by the service, and nothing more. I came up with the following, which is working and functional, but is it SOLID and maintainable? Seems too simple and effective, like I'm missing something.
Requirements:
- load a custom json file
- strongly typed
- not expose more than necessary
- maintainable
I came up with the following.
public Startup(IConfiguration configuration)
{
var configBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile("myappsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
;
Configuration = configBuilder.Build();
}
Using LAMAR, so the following:
public void ConfigureContainer(ServiceRegistry services)
{
var config = new MyAppConfig();
Configuration.GetSection("MyAppConfig").Bind(config);
}
My json file looks like this:
{
"MyAppConfig": {
"AppSettings": {
"Name": "My Application"
},
"DataSettings": {
"PrimaryDB": {
"Name": "DBNAME",
"ConnectionString": "Server=serverAddr.DOMAIN.com;Database=INITIAL_DB_HERE;User Id=MY_APP_USER_NAME;Password=******;MultipleActiveResultSets=true",
"DatabaseName": "DBNAME", // this has a separate use
"Provider": ""
}
}
}
}
To use this, I'm simply passing the config object to the function that creates the service instance, and injecting to the service only what's needed.
services.For<IPerformanceService>().Use(c => CreatePerformanceService(config));
private IPerformanceService CreatePerformanceService(IAppConfiguration appConfig)
{
var myRepo = new PerformanceRepository(appConfig.DataSettings.PrimaryDB.ConnectionString, appConfig.DataSettings.PrimaryDB.DatabaseName);
return new PerformanceService(myRepo);
}