I have a appsettings.json that look like this
{
"AppName": "my-app-service",
"MyModel": {
"MyList": [{
"CountryCode": "jp"
},{
"CountryCode": "us"
}]
}
}
Now, i have a POCO file, (MyList.cs is ommited, it has a single string key countryCode)
public class MyModel
{
public IList<MyList> MyList;
}
I wish to make it so that MyModel can be injected anywhere in my code, how do I do that? I see that people do this in their setup.cs
services.Configure<MyModel>(Configuration.GetSection("MyModel"));
How ever it looks like when I use IOption<MyModel>
in my code in the contructors, I just get null value. Where am I wrong?
You are correct: calling
Configure<T>
sets up the options infrastructure forT
. This includeIOptions<T>
,IOptionsMonitor<T>
andIOptionsSnapshot<T>
. In its simplest forms, configuring the value uses anAction<T>
or as in your example binding to a specificIConfiguration
. You may also stack multiple calls to either form ofConfigure
. This then allows you to accept anIOptions<T>
(or monitor/snapshot) in your class' constructor.The easiest way to determine if binding to an
IConfigurationSection
is working as you intend it to is to manually perform the binding and then inspect the value:The above is dependant on the
Microsoft.Extensions.Configuration.Binder
package which you should already have as a transitive dependency if you are referencing the Options infrastructure.Back to your issue: the binder will only bind
public
properties by default. In your caseMyClass.MyList
is a field. To get the binding to work you must change it to a property instead.If you wanted/needed to bind non-
public
properties you could pass anAction<BinderOptions>
:Even with
BinderOptions
there is still no way to bind to fields. Also note that there is varying behavior for things like collection interfaces, arrays andget
only properties. You may need to play around a bit to ensure things are binding as you intend.