我尝试使用嵌套元素进行配置。 但亲子关系是一对一的,而不是一对多的。 含义 storageProvider 只能有一个 nestedProvider 。
嵌套级别不受限制。
...
<store storeName="123">
<storageProvider type="disk">
<nestedProvider type="share">
<nestedProvider type="amazon-s3">
</nestedProvider>
</nestedProvider>
</storageProvider>
</store>
...
问题 当我使用NestedProvider属性创建StorageProviderElement并尝试读取配置时,我在mscorlib中捕获StackOverflowException。就像.NET中有一个错误(即使用.NET 4.5)
我做错了什么或是预期的行为?
此时我不得不将此属性更改为集合(就像您以其他任何方式进行),但我仍然想知道为什么我不能制作嵌套的一对一元素。
代码: StoreElement
public class StoreElement : ConfigurationElement
{
private const string storeName = "storeName";
private const string storageProvider = "storageProvider";
[ConfigurationProperty(storeName, IsKey = true, IsRequired = true)]
public string StoreName
{
get
{
return (string)base[storeName];
}
}
[ConfigurationProperty(storageProvider, IsRequired = true)]
public StorageProviderElement StorageProvider
{
get
{
return (StorageProviderElement)this[storageProvider];
}
}
}
StorageProviderElement (这是带递归的那个)
public class StorageProviderElement : ConfigurationElement
{
private const string type = "type";
private const string options = "options";
private const string nestedProvider = "nestedProvider";
[ConfigurationProperty(type, IsRequired = true)]
public string Type
{
get
{
return (string)base[type];
}
}
[ConfigurationProperty(options, IsDefaultCollection = false, IsRequired = false)]
public GenericConfigurationElementCollection<StorageProviderOptionElement> Options
{
get
{
return (GenericConfigurationElementCollection<StorageProviderOptionElement>) this[options];
}
}
// this is what trigger stack overflow exception
[ConfigurationProperty(nestedProvider, IsDefaultCollection = false, IsRequired = false)]
public StorageProviderElement NestedProvider
{
get
{
return (StorageProviderElement)this[nestedProvider];
}
}
}
更新 Capitan显然是为了救援。 为过度教育的低调CTO教育屏幕截图:
你不能轻易看到堆叠。
答案 0 :(得分:2)
此异常的来源是ConfigurationElement
:
private static ConfigurationProperty CreateConfigurationPropertyFromAttributes(PropertyInfo propertyInformation)
{
ConfigurationProperty configurationProperty = (ConfigurationProperty) null;
if (Attribute.GetCustomAttribute((MemberInfo) propertyInformation, typeof (ConfigurationPropertyAttribute)) is ConfigurationPropertyAttribute)
configurationProperty = new ConfigurationProperty(propertyInformation);
if (configurationProperty != null && typeof (ConfigurationElement).IsAssignableFrom(configurationProperty.Type))
{
ConfigurationPropertyCollection result = (ConfigurationPropertyCollection) null;
ConfigurationElement.PropertiesFromType(configurationProperty.Type, out result);
}
return configurationProperty;
}
它检查给定属性是否有ConfigurationProperty
属性,如果是,并且属性类型继承自ConfigurationElement
(您的情况) - 它会再次递归地检查该属性类型。如果属性类型与外部类类型相同 - 递归永远不会结束并导致stackoverflow异常。
所以简而言之 - 你不能这样做(当你试图获得相应的部分而不实际调用你的任何方法时会立即抛出stackoverflow):
public class StorageProviderElement : ConfigurationElement
{
[ConfigurationProperty("whatever")]
public StorageProviderElement Whatever
{
get;
}
}
对我来说确实是一个错误,不确定,也许背后有一些有效的推理,但我找不到任何错误。
重现的简短示例:
class Program {
static void Main(string[] args) {
// throws
ConfigurationManager.GetSection("store");
}
}
public class StoreElement : ConfigurationSection
{
[ConfigurationProperty("storageProvider")]
public StorageProviderElement StorageProvider { get; }
}
public class StorageProviderElement : ConfigurationElement {
[ConfigurationProperty("whatever")]
public StorageProviderElement Whatever { get; }
}
在app.config中
<configSections>
<section name="store" type="ConsoleApp4.StoreElement, ConsoleApp4"/>
</configSections>
<store />