具有多个嵌套集合的自定义配置

时间:2019-02-15 09:50:57

标签: c# .net .net-4.5 app-config

我知道已经有很多答案,但是,我读过的答案似乎都不是我想要的。这样做,他们不太正确。所以,请与我一起来。

我正在尝试为c#中的app.config文件创建一个自定义的嵌套配置。我所追求的基本上是这样:

<MyConfigurationSection>
    <CollectionA>
      <CollectionC Property1="Blah" Property2="123" >
        <CollectionD Property1="Achoo" Property2="Bless You">
            <Element Property1="Woo" Property2="Hoo" Property3="456" />
            <Element Property1="Oh" Property2="No" />
        </CollectionD>
        <CollectionD Property1="TaDa" Property2="HaHa!">
            <Element Property1="X" Property2="Y" />
        </CollectionD>
      </CollectionC>
    </CollectionA>
    <CollectionB>
        <CollectionC Property1="Boo" Property2="789">
            <CollectionD Property1="Test" Property2="ing">
                <Element Property1="Please" Property2="Help" />
            </CollectionD>
        </CollectionC>
    </CollectionB>
</MyConfigurationSection>

我已经为自定义配置部分编写了代码,当它仅包含CollectionACollectionB以及Elements时,这不是问题,但是应用程序中需要进行的更改意味着我还需要一些内容复杂。有帮助吗,或者有人给我指明正确的方向?

我说过,我看过其他示例,它们似乎都是CollectionB,嵌套在CollectionA的{​​{1}}部分中-似乎并没有帮助我,或者也许我只是误会了一些东西。

最终,我要实现的是,对于config,将所有collectionA映射到一个对象中,每个CollectionC对象都有它自己的属性,以及一个CollectionC对象的映射(带有元素列表)。然后重复CollectionD

为了完整起见,这是我为此创建的自定义程序集,显然它不起作用,而且我不愿意最初发布,因为我觉得自己离轨道太远了,可能不值得的努力。但是,它仍然在这里:

CollectionB

自然地,配置文件的标题包含相应的namespace my.app.namespace { #region Configuration Section public class MyConfigurationSection : ConfigurationSection { public const string SectionName = "MyConfigurationSection"; [ConfigurationProperty("CollectionA")] public CollectionA CollectionAItems { get { return ((CollectionA)(base["CollectionA"])); } set { base["CollectionA"] = value; } } [ConfigurationProperty("CollectionB")] public CollectionB CollectionBItems { get { return ((CollectionB)(base["CollectionB"])); } set { base["CollectionB"] = value; } } } #endregion Configuration Section #region Configuration Collections //CollectionA that wraps the CollectionC [ConfigurationCollection(typeof(ElementC))] public class CollectionA : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new ElementC(); } protected override object GetElementKey(ConfigurationElement element) { return ((ElementC)element).Property1; } protected override string ElementName { get { return "CollectionA"; } } [ConfigurationProperty("CollectionC")] public CollectionC CollectionCItems { get { return ((CollectionC)(base["CollectionC"])); } set { base["CollectionC"] = value; } } } //CollectionB that wraps CollectionC [ConfigurationCollection(typeof(ElementC))] public class CollectionB : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new ElementC(); } protected override object GetElementKey(ConfigurationElement element) { return ((ElementC)element).Property1; } protected override string ElementName { get { return "CollectionB"; } } [ConfigurationProperty("CollectionC")] public CollectionC CollectionCItems { get { return ((CollectionC)(base["CollectionC"])); } set { base["CollectionC"] = value; } } } //CollectionC that wraps CollectionD [ConfigurationCollection(typeof(ElementD))] public class CollectionC : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new ElementD(); } protected override object GetElementKey(ConfigurationElement element) { return ((ElementD)element).Property1; } protected override string ElementName { get { return "CollectionC"; } } [ConfigurationProperty("CollectionD")] public CollectionD CollectionDItems { get { return ((CollectionD)(base["CollectionD"])); } set { base["CollectionD"] = value; } } } #endregion Configuration Collections #region Configuration Elements //ElementC (element of CollectionC) class ElementC : ConfigurationElement { [ConfigurationProperty("Property1", DefaultValue = "", IsKey = true, IsRequired = true)] public string Property1 { get { return (string)this["Property1"]; } set { this["Property1"] = value; } } [ConfigurationProperty("Property2", DefaultValue = "", IsKey = false, IsRequired = true)] public int Property2 { get { return (int)this["Property2"]; } set { this["Property2"] = value; } } } //ElementD (element of CollectionD) class ElementD : ConfigurationElement { [ConfigurationProperty("Property1", DefaultValue = "", IsKey = true, IsRequired = true)] public string Property1 { get { return (string)this["Property1"]; } set { this["Property1"] = value; } } [ConfigurationProperty("Property2", DefaultValue = "", IsKey = false, IsRequired = true)] public string Property2 { get { return (string)this["Property2"]; } set { this["Property2"] = value; } } } //Element class Element : ConfigurationElement { [ConfigurationProperty("Property1", DefaultValue = "", IsKey = true, IsRequired = true)] public string Property1 { get { return (string)this["Property1"]; } set { this["Property1"] = value; } } [ConfigurationProperty("Property2", DefaultValue = "", IsKey = false, IsRequired = true)] public string Property2 { get { return (string)this["Property2"]; } set { this["Property2"] = value; } } [ConfigurationProperty("Property3", DefaultValue = "", IsKey = false, IsRequired = false)] public int Property3 { get { return (int)this["Property3"]; } set { this["Property3"] = value; } } } #endregion Configuration Elements } 部分:

configSections

为了访问配置,我得到以下内容:

<configSections>
    <section name="MyConfigurationSection" type="my.app.namespace.MyConfigurationSection, my.app.namespace" />
</configSections>

正如我进一步讲的那样,我认为我要实现的目标还有很长的路要走!我试图将//Fails on this line var configSection = ConfigurationManager.GetSection(MyConfigurationSection.SectionName) as MyConfigurationSection; foreach (CollectionA collectionAItems in configSection.CollectionAItems) { //It doesn't even make it into this for each but essentially i'd iterate over collection C, and then each CollectionD in C, and then each Element in CollectionD } CollectionA变成自己的CollectionB,以将其分解一些,但是在这方面也没有取得太大进展。

0 个答案:

没有答案