Reputation: 105
I come across some strangeness while debugging another issue and wondering if someone with more knowledgeable could explain. Here is some quick test code (I apologies for any errors)
AppSetting
{
"A": {
"B": 123,
"C": "ABC"
}
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
var config1 = Configuration.GetSection("A");
//config1.value <- Null
var config2 = Configuration.GetSection("A:B");
//config2.value <- 123
var config3 = Configuration.GetSection("A:C");
//config3.value <- "ABC"
services.Configure<ABC>(config1);
services.AddTransient<ABCService>();
}
public class ABC
{
public int B {get;set;}
public string c {get;set;}
}
public class ABCService
{
public ABCService(IOptions<ABC> abcConfig)
{
//abcConfig.Value.B <- 123
//abcConfig.Value.C <- "ABC"
}
}
Why is config1.value
null in ConfigureServices
but after dependency injection abcConfig
in ABCService
has values?
Upvotes: 0
Views: 446
Reputation: 93153
config1.value
is null
simply because, in your example JSON, there is no value for A
. The configuration system works with simple key value pairs. For example, in your built Configuration
object, you have the following (key => value):
A =>
A:B => 123
A:C => ABC
You can see this for yourself if you run the following sample code, which generates the output shown above:
Configuration.AsEnumerable()
.ToList()
.ForEach(x => Console.WriteLine("{0} => {1}", x.Key, x.Value));
This shows that the value for A
is null
, which is what you have described. There are values for both A:B
and A:C
, which are part of the A
section as denoted by the :
hierarchy separator. When you use services.Configure
, it's really just matching anything under A:
against your ABC
class, where it finds B
and C
accordingly.
By using GetSection("A")
, you've created a different view of your Configuration
instance that will only include anything rooted at A
. In your example, it's the same in both cases as you only have A
.
The docs do a great job of describing how the configuration system works.
Upvotes: 1
Reputation: 116
You can add a constructor to your startup class and put IConfiguration as a dependency. that will be the resolved configuration object. You can then use that in your ConfigureServices method.
You can see an example here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.1
Upvotes: 0