I'm trying to use strongly typed json config settings as per the Options pattern in .net core. All examples so far show how easy it is to inject the strongly typed settings class into a controller but I need to use it in a middleware class (Very similar to this question but I'm no further forward after trying it that way).
So, the setup:
mysettings.json
{
"MySettings": {
"Name": "Some Name from config",
"Description": "Some Description from config"
}
}
mysettings.cs
public class MySettings
{
public string Name { get; set; } = "Default name";
public string Description { get; set; } = "Default description";
}
startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Add functionality to inject IOptions<T>
services.AddOptions();
// Add our Config object so it can be injected
services.Configure<MySettings>(Configuration.GetSection("MySettings"));
services.AddSingleton<IMySettingsService, MySettingsService>();
}
MysettingsService.cs
public class MysettingsService : IMysettingsService
{
private MySettings mySettings { get; set; }
public MysettingsService (MySettings _mySettings)
{
mySettings = _mySettings.value;
}
public string GetName()
{
return mySettings.Name;
}
}
How do I go about instantiating MysettingsService.cs and injecting an IOptions<MySettings>
into the class constructor so I can call the GetName method?
Few points:
services.AddSingleton<IMysettingsService, MysettingsService >(i => new MysettingsService ());
Follow these steps:
Define MySettings
public class MySettings
{
public string Name { get; set; }
public string Description { get; set; }
}
Define MySettingsService
public class MySettingsService : IMySettingsService
{
private readonly MySettings mySettings;
public MySettingsService (IOptions<MySettings> _mySettings)
{
mySettings = _mySettings.Value;
}
public string GetName()
{
return mySettings.Name;
}
}
In Startup
services.Configure<MySettings>(this.Configuration.GetSection("MySettings"));
services.AddSingleton<IMySettingsService, MySettingsService >();
EDITED -- I am including the implementation for you to follow
I have created a sample application and it works for me; Please follow the steps below:
Few details.
My application name is: SettingsApp
mySettings.json
- with the contents{ "MySettings": { "Name": "Some Name from config", "Description": "Some Description from config" } }
Startup
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("mySettings.json", true, reloadOnChange: true) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); if (env.IsDevelopment()) { // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. builder.AddApplicationInsightsSettings(developerMode: true); } Configuration = builder.Build(); }
See the line:
.AddJsonFile("mySettings.json", true, reloadOnChange: true)
MySettings
object to hold the settingsnamespace SettingsApp.Initialisations { public class MySettings { public string Name { get; set; } public string Description { get; set; } } }
Note: I use the namespace SettingsApp.Initialisations
to keep this file. You can choose any based on your application structure.
IMySettingsService
namespace SettingsApp.Services { public interface IMySettingsService { string GetName(); } }
Note: I use the namespace SettingsApp.Services
for this.
IMySettingsService
using SettingsApp.Initialisations; using Microsoft.Extensions.Options; namespace SettingsApp.Services { public class MySettingsService : IMySettingsService { private readonly MySettings mySettings; public MySettingsService(IOptions<MySettings> _mySettings) { mySettings = _mySettings.Value; } public string GetName() { return mySettings.Name; } } }
Startup.ConfigureServices
method// This method gets called by the run time. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Options services.AddOptions(); services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); services.AddSingleton<IMySettingsService, MySettingsService>(); // Add framework services. services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc(); }
Note to include the required using's.
Check the code below on how this is done:
// Options services.AddOptions(); services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); services.AddSingleton<IMySettingsService, MySettingsService>();
HomeController
for testing.)public class HomeController : Controller { private IMySettingsService mySettingsService; public HomeController(IMySettingsService settingsService) { mySettingsService = settingsService; } public IActionResult Index() { // Get the settings var name = mySettingsService.GetName(); return View(); } ...
In newer version of .NET above binding method does not work anymore.
I have created an extension method that works:
public static void AddSettings<T>(this IServiceCollection serviceCollection, IConfiguration configuration) where T : class, new()
{
var settings = new T();
configuration.Bind(typeof(T).Name, settings);
serviceCollection.AddSingleton(settings);
}
Use it like this:
services.AddSettings<LoggingSettings>(configuration);
Full example:
string pathToConfigFile = "c:\\config.json";
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile(pathToConfigFile, optional: false, reloadOnChange: true)
.Build();
var services = new ServiceCollection()
services.AddSingleton(configuration);
services.AddSettings<ConnectionSettings>(configuration);
services.AddSettings<LoggingSettings>(configuration);
services.AddSettings<AutoCreateSettings>(configuration);
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