c# - 具有递归 ConfigurationElement 的自定义配置部分
问题描述
我正在尝试创建一个表示以下 xml 结构的自定义配置部分:
<observerSettings>
<jobSettings>
<filter key="location" value="de">
<filter key="type" value="MyType1">
<filter key="status" value="failed">
<actions>
<notify timespan="12.00:00:00">
<mailSettings>
<mailAddress to="mail1@something.com" />
<mailAddress to="mail2@something.com" />
</mailSettings>
</notify>
<remove timespan="14.00:00:00">
<mailSettings>
<mailAddress to="mail1@something.com" />
<mailAddress to="mail2@something.com" />
</mailSettings>
</remove>
</actions>
</filter>
</filter>
</filter>
</jobSettings>
</observerSettings>
是这样定义的FilterConfigElement
:
internal class FilterConfigElement : ConfigurationElement, IFilterConfigElement
{
[ConfigurationProperty("filter", IsRequired = false)]
public FilterConfigElement ChildFilter => base["filter"] as FilterConfigElement;
[ConfigurationProperty("actions", IsRequired = false)]
public ActionsConfigElement Actions => base["actions"] as ActionsConfigElement;
[ConfigurationProperty("key", IsRequired = true)]
public string Key => base["key"] as string;
[ConfigurationProperty("value", IsRequired = false)]
public string Value => base["value"] as string;
}
当访问如下配置部分时,应用程序崩溃并出现StackOverflow
异常:
internal class ObserverSettings : ConfigurationSection, IObserverSettings
{
public static IObserverSettings Instance { get; private set; } = ConfigurationManager.GetSection("observerSettings") as ObserverSettings;
[ConfigurationProperty("jobSettings")]
protected JobSettingsCollection JobSettingsCollection => base["jobSettings"] as JobSettingsCollection;
public virtual IJobSettingsCollection JobSettings => JobSettingsCollection;
}
所以我假设ConfigurationManager
正在创建这个具有无限深度的结构,并且在filter
到达最后一个元素时不会停止。这可以以某种方式限制吗?甚至支持这种结构吗?
解决方案
好的,在深入研究实现之后ConfigurationElement
,似乎根本不可能按照我尝试的方式创建递归结构。
问题的原因是在调用之后执行PropertiesFromType
where 属性的分配,从而创建了一个无休止的递归 where is always 。s_propertyBags
CreatePropertyBagFromType
properties
null
private static bool PropertiesFromType(Type type, out ConfigurationPropertyCollection result)
{
ConfigurationPropertyCollection properties = (ConfigurationPropertyCollection)s_propertyBags[type];
result = null;
bool firstTimeInit = false;
if (properties == null) /*code omitted*/
{
properties = CreatePropertyBagFromType(type);
s_propertyBags[type] = properties;
firstTimeInit = true;
}
result = properties;
return firstTimeInit;
}
编辑:
保持某种“递归”结构的唯一解决方法是将所有 child 包装FilterConfigElement
成一个ConfigurationElementCollection
with element name childFilter
。这导致遵循不太好但可接受的配置结构:
<jobSettings>
<filter key="location" value="de">
<childFilter>
<filter key="type" value="MyType1">
<childFilter>
<filter key="status" value="failed">
<actions>
<!-- ... -->
</actions>
</filter>
</childFilter>
</filter>
</childFilter>
</filter>
</jobSettings>
来源:c# 中的递归自定义配置
推荐阅读
- java - 将工作应用程序从一台电脑复制到另一台电脑的安全性
- python - 如何在张量流中按名称重置图形?
- assembly - 用这个斐波那契序列问题和用于制作汇编代码的指令集
- pointers - 怎样才能强制 Rust 获得分配的内存的所有权,而不是通过其安全方法分配的内存?
- google-cloud-platform - 无法为谷歌云 TPU 找到 python api
- angular - 如何在 Syncfusion Angular Grid 中扩展单元格?
- php - 无法使用 try catch 更新用户 laravel
- javascript - 更改引导程序 4.2 轮播持续时间
- design-patterns - 阐明组合关系
- sql-server - 此问题中概述的四种设计中哪一种会产生最佳插入时间?