如何使用绑定读取数组配置部分?

How to read array configuration sections with binding?

如何使用带绑定的 Microsoft.Extensions.Configuration 读取一组配置值?

例如,给定以下 XML 配置:

<root>
    <eventConfiguration>
        <event name="0" source="" type="" target="" />
        <event name="1" source="" type="" target="" />
        <event name="2" source="" type="" target="" />
    </eventConfiguration>
</root>

以及以下 类:

public class Configuration
{
    public EventConfiguration EventConfiguration {get; set;}
}

public class EventConfiguration
{
    public List<Event> Events {get; set;}
}

public class Event
{
    public string Name {get; set;}
    public string Source {get; set;}
    public string Type {get; set;}
    public string Target {get; set;}
}

当我尝试获取配置实例时,事件列表为空:

IConfigurationBuilder builder = new ConfigurationBuilder();
builder.AddXmlFile("default.xml");
var root = builder.Build();
    
// with binding
var configuration = root.Get<Configuration>();
var events = configuration.EventConfiguration.Events; // null

// without binding
var eventSource = root.GetValue("eventConfiguration:event:0:source", default(string)); // not null

解决方案是将 ConfigurationKeyNameAttribute 添加到 Events 属性,因为 XML 元素的名称是 event 而不是 events

public class EventConfiguration
{
    [ConfigurationKeyName(nameof(Event))]
    public List<Event> Events { get; set; }
}

更新#1:

这是我的有效代码。

ConsoleApp1.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="6.0.0" />
  </ItemGroup>

  <ItemGroup>
    <None Update="default.xml">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

default.xml

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <eventConfiguration>
    <event name="0" source="" type="" target="" />
    <event name="1" source="" type="" target="" />
    <event name="2" source="" type="" target="" />
  </eventConfiguration>
</root>

Program.cs

using Microsoft.Extensions.Configuration;

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddXmlFile("default.xml");
            var configurationRoot = builder.Build();

            // with binding
            var configuration = configurationRoot.Get<Configuration>();
            var events = configuration.EventConfiguration.Events;

            Console.WriteLine($"events.Count = [{events?.Count}]");

            for (int i = 0; i < (events?.Count ?? 0); i++)
            {
                Console.WriteLine(events[i]);
            }

            // without binding
            var eventSource = configurationRoot.GetValue("eventConfiguration:event:0:source", default(string));
        }
    }

    public class Configuration
    {
        public EventConfiguration EventConfiguration { get; set; }
    }

    public class EventConfiguration
    {
        [ConfigurationKeyName(nameof(Event))]
        public List<Event> Events { get; set; }
    }

    public class Event
    {
        public string Name { get; set; }
        public string Source { get; set; }
        public string Type { get; set; }
        public string Target { get; set; }

        public override string ToString()
        {
            return $"Event: Name=[{Name}]";
        }
    }
}

输出为:

events.Count = [3]
Event: Name=[0]
Event: Name=[1]
Event: Name=[2]

P:\Projects\ConsoleApp1\ConsoleApp1\bin\Debug\netcoreapp3.1\ConsoleApp1.exe (process 15136) exited with code 0.
Press any key to close this window . . .