我正在尝试创建一个表示以下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元素时不会停止。这能以某种方式受到限制吗?这种结构是否得到了支持?
发布于 2019-09-18 15:54:50
好的,在深入研究了ConfigurationElement的实现之后,似乎根本不可能像我尝试的那样创建递归结构。
问题的原因是PropertiesFromType的实现,其中将属性分配给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;
}编辑:
保持某种“递归”结构的唯一解决办法是将所有子FilterConfigElement包装到一个元素名为childFilter的ConfigurationElementCollection中。这导致下面的配置结构不是很好,但可以接受:
<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>https://stackoverflow.com/questions/57973983
复制相似问题