有没有一种方法可以覆盖已由 auto-属性 初始化语法使用 .Net Core 中的配置值初始化的集合?

Is there a way to override collection that has been initialized by auto-property initialize syntax with values from configuration in .Net Core?

我有一个 class 保存我的配置值:

public class DummyConfiguration
    {
        public List<DummyConfigurationObject> DummyConfigurationCollection { get; set; } =
            new List<DummyConfigurationObject>
            {
                new DummyConfigurationObject
                {
                    DummyField = "DummyConfigurationObject1",
                },
                new DummyConfigurationObject
                {
                    DummyField = "DummyConfigurationObject2",
                },
            };
    }

我使用自动初始化的属性来提供一些适合我的合理默认值。

这是我的 appsettings.yaml:

DummyConfigurationCollection:
    - DummyField: DummyConfigurationObject3
    - DummyField: DummyConfigurationObject4
    - DummyField: DummyConfigurationObject5

当我调用 configuration.Get().DummyConfigurationCollection.Count 时,我会得到 5 个原因,因为集合已经初始化,默认活页夹仅使用 Add 方法添加其他条目。但是我想要的是完全替换我的默认值,如果我的配置文件中有一些值对应于这个 属性。

这可以使用默认配置活页夹吗?

是的,您可以像这样配置您的应用程序:

services.Configure<DummyConfiguration>(options => {
 DummyConfiguration.DummyConfigurationCollection.Clear();
 return Configuration.GetSection("DummyConfiguration").Bind(options)
});

它是 Configure 的重载,允许您配置绑定的完成方式。在这种情况下,我们在绑定实际配置值之前清除生成的选项实例上的所有条目。

稍后您可以在任何其他带有 IOptions<DummyConfiguration> 的服务上使用它,它将只显示配置的值,而不是默认值。

这是我在 github 上进行测试的回购协议:https://github.com/bison92/IConfigurationCollectionBinding/tree/c29534f41cf07ea22107493d45999fe546462406

编辑

因为你想使用 Configuration.Get() 没有办法修改它的行为,除了指定你是否想尝试绑定私有属性 AFAIK。

因此,您可能想尝试实现您的自定义 ICollection,例如使用 2 个列表(默认值、电流)支持它并覆盖其方法,以便它以电流或默认值响应,但始终修改电流。

public class DefaultBackedCollection<T> : ICollection<T>
{
    private readonly IList<T> defaults;
    private readonly IList<T> currents = new List<T>();
    public DefaultBackedCollection(List<T> defaultElements)
    {
        defaults = defaultElements ?? new List<T>();
    }
    public int Count => currents.Any() ? currents.Count : defaults.Count;

    public bool IsReadOnly => false;

    public void Add(T item)
    {
        currents.Add(item);
    }

    public void Clear()
    {
        currents.Clear();
    }

    public bool Contains(T item)
    {
        return currents.Any() ? currents.Contains(item) : defaults.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        if (currents.Any())
        {
            currents.CopyTo(array, arrayIndex);
        }
        else 
        {
            defaults.CopyTo(array, arrayIndex); 
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return currents.Any() ? currents.GetEnumerator() : defaults.GetEnumerator();
    }

    public bool Remove(T item) => currents.Remove(item);

    IEnumerator IEnumerable.GetEnumerator()
    {
        return currents.Any() ? currents.GetEnumerator() : defaults.GetEnumerator();
    }
}

看看更新后的工作示例:https://github.com/bison92/IConfigurationCollectionBinding