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

  1. Create the settings files - mySettings.json - with the contents
{
  "MySettings": {
    "Name": "Some Name from config",
    "Description": "Some Description from config"
  }
}
  1. 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)

  1. 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.

  1. Create the interface IMySettingsService
namespace SettingsApp.Services
{
    public interface IMySettingsService
    {
        string GetName();
    }
}

Note: I use the namespace SettingsApp.Services for this.

  1. 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;
        }
    }
}
  1. 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>();
  1. 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();
    }

...
  1. See the results:

Home controller constructor Inside the action


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);