Custom Configuration for app.config - collections of sections?
我的头打得真厉害!我以前做过,但没有像现在这样"深入"或复杂,我尝试过不同的方法来实现这一点,但都失败了。
因此,这是我在app.config中想要的自定义XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <Profiles> <!--Collection--> <Profile Name="Live"> <Components> <Component Name="Portal" Type="Web" /> <Component Name="Comms" Type="Web" /> <Component Name="Scheduler" Type="WindowsService" ServiceName="LiveScheduler" /> </Components> <Databases> <Database Name="Main" Connection="Data Source=.\SQL2008" /> <Database Name="Staging" Connection="Data Source=SomeSite.co.uk" /> </Databases> </Profile> <Profile Name="Test"> <Components> <Component Name="Portal" Type="Web" /> <Component Name="Comms" Type="Web" /> <Component Name="Scheduler" Type="WindowsService" ServiceName="TestScheduler" /> </Components> <Databases> <Database Name="Main" Connection="Data Source=.\SQL2008" /> <Database Name="Staging" Connection="Data Source=Internal" /> </Databases> </Profile> </Profiles> |
所以一个配置文件集合,每个配置文件都有一个子元素集合(组件是一个集合,然后组件是一个元素)
但是,除了多个配置文件之外,我目前拥有所有这些配置文件。我确实看到了问题,但不确定如何"解决"它。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | public class Profile : ConfigurationSection { [ConfigurationProperty("Name", IsRequired=true)] public string Name { get { return base["Name"] as string; } set { base["Name"] = value; } } [ConfigurationProperty("Components")] public ComponentCollection Components { get { return ((ComponentCollection)(base["Components"])); } } [ConfigurationProperty("Databases")] public DatabaseCollection Databases { get { return ((DatabaseCollection)(base["Databases"])); } } } [ConfigurationCollection(typeof(Component), AddItemName="Component")] public class ComponentCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new Component(); } protected override object GetElementKey(ConfigurationElement element) { return ((Component)(element)).Name; } public Component this[int idx] { get { return base.BaseGet(idx) as Component; } set { if (base.BaseGet(idx) != null) { base.BaseRemoveAt(idx); } this.BaseAdd(idx, value); } } public Component this[string key] { get { return base.BaseGet(key) as Component; } set { if (base.BaseGet(key) != null) { base.BaseRemove(key); } this.BaseAdd(this.Count, value); } } } public class Component : ConfigurationElement { [ConfigurationProperty("Type", IsRequired = true)] public string Type { get { return this["Type"] as string; } set { this["Type"] = value; } } [ConfigurationProperty("Name", IsRequired = true, IsKey = true)] public string Name { get { return this["Name"] as string; } set { this["Name"] = value; } } [ConfigurationProperty("ServiceName", IsRequired = false)] public string ServiceName { get { return this["ServiceName"] as string; } set { this["ServiceName"] = value; } } } [ConfigurationCollection(typeof(Database), AddItemName ="Database")] public class DatabaseCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new Database(); } protected override object GetElementKey(ConfigurationElement element) { return ((Database)(element)).Name; } public Database this[int idx] { get { return base.BaseGet(idx) as Database; } set { if (base.BaseGet(idx) != null) { base.BaseRemoveAt(idx); } this.BaseAdd(idx, value); } } public Database this[string key] { get { return base.BaseGet(key) as Database; } set { if (base.BaseGet(key) != null) { base.BaseRemove(key);; } this.BaseAdd(this.Count, value); } } } public class Database : ConfigurationElement { [ConfigurationProperty("Name", IsKey = true, IsRequired = true)] public string Name { get { return this["Name"] as string; } set { this["Name"] = value; } } [ConfigurationProperty("Connection", IsKey = false, IsRequired = true)] public string Connection { get { return this["Connection"] as string; } set { this["Connection"] = value; } } } |
您需要将配置部分移到更高一级。
1 2 3 4 5 6 7 8 9 10 11 | public class Profiles : ConfigurationSection { [ConfigurationProperty("Profile")] public ProfileCollection Profile { get { return this["profile"] as ProfileCollection; } } } |
这是我创建的一个分区。您应该能够通过以下方式来工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | public class ImportConfiguration : ConfigurationSection { [ConfigurationProperty("importMap")] public ImportMapElementCollection ImportMap { get { return this["importMap"] as ImportMapElementCollection; } } } public class ImportColumnMapElement : ConfigurationElement { [ConfigurationProperty("localName", IsRequired = true, IsKey = true)] public string LocalName { get { return this["localName"] as string; } set { this["localName"] = value; } } [ConfigurationProperty("sourceName", IsRequired = true)] public string SourceName { get { return this["sourceName"] as string; } set { this["sourceName"] = value; } } } public class ImportMapElementCollection : ConfigurationElementCollection { public ImportColumnMapElement this[object key] { get { return base.BaseGet(key) as ImportColumnMapElement; } } public override ConfigurationElementCollectionType CollectionType { get { return ConfigurationElementCollectionType.BasicMap; } } protected override string ElementName { get { return"columnMap"; } } protected override bool IsElementName(string elementName) { bool isName = false; if (!String.IsNullOrEmpty(elementName)) isName = elementName.Equals("columnMap"); return isName; } protected override ConfigurationElement CreateNewElement() { return new ImportColumnMapElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((ImportColumnMapElement)element).LocalName; } } |
您的实现是正确的,除非您需要一个额外的级别。将配置文件从配置节更改为配置元素,然后生成包含配置文件项集合的配置节配置文件。
对于自动化测试来说,这是一个很好的例子,在没有配置部分的情况下进行调试是一个巨大的痛苦。