Stack Undefined
Stack Undefined

Reputation: 1340

Can't bind AppSettings to IOptions in .NET 6 console app

Working in a .NET 6 console app and having problem with binding settings from appsettings.json to IOptions.

Here is my code:

appsettings.json

{
    "MyOptionsSettings" : {
       "Foo": 100,
       "Bar": true
    }
}

MyOptions.cs

public class MyOptions 
{
   public int Foo {get; set;}
   public bool Bar {get; set;}
}

program.cs

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

var builder = Host.CreateDefaultBuilder(args);

builder.ConfigureServices((hostContext, services) => 
{
    var configuration = hostContext.Configuration;
    services.Configure<MyOptions>(opts => configuration.GetSection("MyOptionsSettings"));
    services.AddTransient<MyService>();
});

var app = builder.Build();
var myService = app.Services.GetService<MyService>();

MyService.cs

public class MyService 
{
    .
    .
    public MyService(IOptions<MyOptions> options)
    {
       _options = options;
    } 
    .
    .
}

The _options has default values for all the properties and nothing from the appsettings. I actually want to use the IOptions<T> wrapper IOptionsMonitor<T> so the settings are dynamic. However, I can't even get the IOptions<T> work. I think my problem is with the IServiceCollection.Configure<T>().

Update:

I just came across a blog that probably solved my issue but I'm not sure why the example above isn't. Based on the blog, I changed the following line:

From this:

services.Configure<MyOptions>(opts => configuration.GetSection("MyOptionsSettings")); 

To This:

services.Configure<MyOptions>(opts => configuration.GetSection("MyOptionsSettings").Bind(opts));

Now the IOptions binds/resolves without any issues. Even Microsoft's console app documentation uses the one above (without the Bind(opts)); What's the difference between those two lines?

Upvotes: 3

Views: 1960

Answers (1)

Guru Stron
Guru Stron

Reputation: 143023

There are OptionsConfigurationServiceCollectionExtensions.Configure and OptionsServiceCollectionExtensions.Configure with several overloads former accepting IConfiguration and latter - Action<TOptions>, so the first one will accept the confiuration from which to bind the options and second one will require some action to fill the option values. So your original snippet can also be:

services.Configure<MyOptions>(configuration.GetSection("MyOptionsSettings")); // IConfigurationSection is IConfiguration

Or you can use the Bind approach, but usually the Action<TOptions> variant usually is used for "manual" configuration like:

builder.Services.Configure<JsonOptions>(opts =>
    opts.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.Never);

Upvotes: 0

Related Questions