“配置”部分在“启动”中为空,但在服务中填充

时间:2018-08-08 14:24:54

标签: c# asp.net-core .net-core asp.net-core-2.0

在调试另一个问题时,我遇到了一些陌生之处,想知道是否有更多知识渊博的人可以解释。这是一些快速测试代码(对于任何错误,我深表歉意)

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"
        }
}

为什么config1.value中的ConfigureServices为null,但在abcConfig中的依赖注入ABCService之后却有值?

2 个答案:

答案 0 :(得分:1)

config1.value之所以是null,仅仅是因为在您的示例JSON中,A没有 value 。配置系统使用简单的键值对。例如,在构建的Configuration对象中,您具有以下内容(键=>值):

A =>
A:B => 123
A:C => ABC

如果运行以下示例代码,您将自己看到此代码,该示例代码生成上面显示的输出:

Configuration.AsEnumerable()
    .ToList()
    .ForEach(x => Console.WriteLine("{0} => {1}", x.Key, x.Value));

这表明A的值为null,这就是您所描述的。 A:BA:C都有值,它们是A 部分的一部分,由:层次分隔符表示。当您使用services.Configure时,实际上就是将A:下的任何内容与您的ABC类进行匹配,并在其中相应地找到BC

通过使用GetSection("A"),您为Configuration实例创建了一个不同的视图,该视图仅包含以A为根的任何内容。在您的示例中,这两种情况都是相同的,因为您只有A

docs在描述配置系统如何工作方面做得很好。

答案 1 :(得分:0)

您可以将构造函数添加到启动类中,并将IConfiguration作为依赖项。那将是解析的配置对象。然后,您可以在ConfigureServices方法中使用它。

您可以在此处查看示例: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.1