Passing IOptions into .Net core middleware class for json config retrieval
Few points:
- Constructor is missing in the mentioned class - MysettingsService
- Did you register the implementation of IMysettingsService in Startup class?
- While registering the implementation, you can initialize the MysettingsService, like below:
services.AddSingleton<IMysettingsService, MysettingsService >(i => new MysettingsService ());
Follow these steps:
- Make sure that you have registered your JSON file - mysettings.json - in ConfigurationBuilder
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
- Create the settings files -
mySettings.json
- with the contents
{ "MySettings": { "Name": "Some Name from config", "Description": "Some Description from config" } }
- Configure it in the
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)
- Create
MySettings
object to hold the settings
namespace 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.
- Create the interface
IMySettingsService
namespace SettingsApp.Services { public interface IMySettingsService { string GetName(); } }
Note: I use the namespace SettingsApp.Services
for this.
- Implement the interface -
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; } } }
- Add the options and let the system know your implementation in
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>();
- Use the implementation (I am using the
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(); } ...
- See the results:
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);