3

So I was trying to follow the Microsoft Docs, Options pattern in ASP.NET Core however for the life of me I can't seem to correctly get the "AppSettings" section to my AppSettings object as an option. Configuration.GetSection("AppSettings"); is returning null for me yet

appsettings.Development.json

{
  "AppSettings": {
    "Secret": "DEVELOPMENTTOKENTEST"
  },
  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Default": "Information",
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName" ],
    "Properties": {
      "Application": "Oasis.API"
    },
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "Logs/api_.log",
          "outputTemplate": "{Timestamp:o} [{Level:u3}] ({SourceContext}) {Message}{NewLine}{Exception}",
          "rollingInterval": "Day",
          "retainedFileCountLimit": 1
        }
      }
    ]
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=JS-PC;Initial Catalog=Oasis;Integrated Security=True"
  }
}

Class for my AppSettings section.

public class AppSettings
{
        public string Secret { get; set; }
}

How I am trying to read in the section and configure it for dependency injection for use in a service.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
            services.AddCors();
            services.AddControllers();

            // Configure API secret
            var test = Configuration.GetSection("AppSettings"); // null... oh?
            services.Configure<AppSettings>(con => Configuration.GetSection("AppSettings").Bind(con));

            // Swagger generation
            services.AddSwaggerGen();

            // Database and Repositories
            ConfigureRepositories(services);
            
            // Register Services
            ConfigureServiceClasses(services);
}

Here is how I have it setup to take the IOptions in my service.
WebUserService.cs

public class WebUserService : IWebUserService
{
        private readonly ILogger<WebUserService> _logger;

        private readonly IWebUserRepository _webUserRepository;

        private readonly AppSettings _appSettings;

        public WebUserService(ILogger<WebUserService> logger, IWebUserRepository webUserRepository, IOptions<AppSettings> appSettings)
        {
            _logger = logger;
            _webUserRepository = webUserRepository;
            _appSettings = appSettings.Value;
        }
}

enter image description here

Marc Wittke
  • 2,991
  • 2
  • 30
  • 45
Jdog
  • 35
  • 8
  • Apparently this works to create my AppSettings object with a correct Secret property from appsettings.Development.json `var test = Configuration.GetSection("AppSettings").Get();` however I don't know of a way to inject it via services.Configure(); – Jdog Jan 17 '21 at 23:59
  • Hi @Jdog,any update about this case? – Yinqiu Jan 18 '21 at 02:50
  • If you have any progress or errors, you can tell me the first time so that I can solve the problem for you. – Yinqiu Jan 18 '21 at 03:02
  • @Yinqiu I think I finally figured out why I am getting null for my `_appSettings = appSettings.Value;` and that is because I'm trying to DI IOptions in one of my services that is in a class library that does not reference my API project. – Jdog Jan 18 '21 at 03:02
  • Hi @,Have you solved this issue?Is there any other question? – Yinqiu Jan 18 '21 at 03:11
  • Your answer gave me enough to go on and made me realize the root of my issue and now I just need to pick how I want to design my code using what you have provided. Marking your response as answer. Thank you for helping me out. – Jdog Jan 18 '21 at 03:19
  • 1
    Thanks.Glad can help you :) – Yinqiu Jan 18 '21 at 03:20

1 Answers1

2

You don't need to setup.Its implementation will be injected by the DI system.You can use following to get the Secret:

using Microsoft.Extensions.Configuration;
//....
private readonly IConfiguration _mySettings;
public HomeController(IConfiguration mySettings)
    {
        _mySettings = mySettings;
    }
public IActionResult Index()
    {
        var result = _mySettings.GetValue<string>("AppSettings:Secret");
        //...
    }

Test Result: enter image description here

By the way, if you want to inject it,you can use following code.

 //...
  var settingsSection =Configuration.GetSection("AppSettings");
  services.Configure<AppSettings>(settingsSection);

In controller:

 private readonly IConfiguration _mySettings;
 private readonly AppSettings _settings;

 public HomeController(IOptions<AppSettings> settingsAccessor, IConfiguration mySettings)
    {
        _mySettings = mySettings;
         _settings = settingsAccessor.Value;
    }
  public IActionResult Index()
    {
        var vm = new AppSettings
        {
          Secret= _settings.Secret
        };
        var result = _mySettings.GetValue<string>("AppSettings:Secret");
    }

Test result: enter image description here

Refer to this thread.

Yinqiu
  • 6,609
  • 1
  • 6
  • 14
  • When I follow the way of injecting it like you demonstrated in the second part of your answer, when I perform the same action as you do for `_settings = settingsAccessor.Value;` I'm getting null for this. – Jdog Jan 18 '21 at 02:52
  • Make sure your code is same as mine.Please check it. – Yinqiu Jan 18 '21 at 02:53