有没有一种方法可以覆盖已由 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
我有一个 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