如何在ConfigurationElementCollection中拥有自定义属性?

配置如下

  ... other entries  

实现MyCollection时,我该怎么做“默认”属性?

假设你有这个.config文件:

   
// update type & assembly names accordingly

然后,使用此代码:

 public class MySection : ConfigurationSection { [ConfigurationProperty("MyCollection", Options = ConfigurationPropertyOptions.IsRequired)] public MyCollection MyCollection { get { return (MyCollection)this["MyCollection"]; } } } [ConfigurationCollection(typeof(EntryElement), AddItemName = "entry", CollectionType = ConfigurationElementCollectionType.BasicMap)] public class MyCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new EntryElement(); } protected override object GetElementKey(ConfigurationElement element) { if (element == null) throw new ArgumentNullException("element"); return ((EntryElement)element).Name; } [ConfigurationProperty("default", IsRequired = false)] public string Default { get { return (string)base["default"]; } } } public class EntryElement : ConfigurationElement { [ConfigurationProperty("name", IsRequired = true, IsKey = true)] public string Name { get { return (string)base["name"]; } } } 

您可以使用’default’属性读取配置,如下所示:

  MySection section = (MySection)ConfigurationManager.GetSection("mySection"); Console.WriteLine(section.MyCollection.Default); 

这将输出“一个”

我不知道ConfigurationElementCollection中是否可以有一个默认值。 (它没有看到默认值的任何属性)。

我想你必须自己实现这个。 请看下面的例子。

 public class Repository : ConfigurationElement { [ConfigurationProperty("key", IsRequired = true)] public string Key { get { return (string)this["key"]; } } [ConfigurationProperty("value", IsRequired = true)] public string Value { get { return (string)this["value"]; } } } public class RepositoryCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new Repository(); } protected override object GetElementKey(ConfigurationElement element) { return (element as Repository).Key; } public Repository this[int index] { get { return base.BaseGet(index) as Repository; } } public new Repository this[string key] { get { return base.BaseGet(key) as Repository; } } } public class MyConfig : ConfigurationSection { [ConfigurationProperty("currentRepository", IsRequired = true)] private string InternalCurrentRepository { get { return (string)this["currentRepository"]; } } [ConfigurationProperty("repositories", IsRequired = true)] private RepositoryCollection InternalRepositories { get { return this["repositories"] as RepositoryCollection; } } } 

这是XML配置:

        

然后,在您的代码中,使用以下命令访问默认项:

 MyConfig conf = (MyConfig)ConfigurationManager.GetSection("myConfig"); string myValue = conf.Repositories[conf.CurrentRepository].Value; 

当然,MyConfig类可以隐藏访问Repositories和CurrentRepository属性的详细信息。 您可以在MyConfig类中拥有一个名为DefaultRepository(类型为Repository)的属性来返回此属性。

这可能有点晚,但可能对其他人有所帮助。

这是可能的,但有一些修改。

  • ConfigurationElementCollectioninheritanceConfigurationElement,因为“this [string]”在ConfigurationElement中可用。

  • 通常当ConfigurationElementCollection在另一个类中inheritance并实现时,“this [string]”隐藏为“new this [string]”。

  • 解决它的一种方法是创建this []的另一个实现,例如“this [string,string]”

见下面的例子。

 public class CustomCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new CustomElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((CustomElement)element).Name; } public CustomElement this[int index] { get { return (CustomElement)base.BaseGet(index); } set { if (BaseGet(index) != null) BaseRemoveAt(index); BaseAdd(index, value); } } // ConfigurationElement this[string] now becomes hidden in child class public new CustomElement this[string name] { get { return (CustomElement)BaseGet(name); } } // ConfigurationElement this[string] is now exposed // however, a value must be entered in second argument for property to be access // otherwise "this[string]" will be called and a CustomElement returned instead public object this[string name, string str = null] { get { return base[name]; } set { base[name] = value; } } } 

如果你想对它进行泛化,这应该会有所帮助:

 using System.Configuration; namespace Abcd { // Generic implementation of ConfigurationElementCollection. [ConfigurationCollection(typeof(ConfigurationElement))] public class ConfigurationElementCollection : ConfigurationElementCollection where T : ConfigurationElement, IConfigurationElement, new() { protected override ConfigurationElement CreateNewElement() { return new T(); } protected override object GetElementKey(ConfigurationElement element) { return ((IConfigurationElement)element).GetElementKey(); } public T this[int index] { get { return (T)BaseGet(index); } } public T GetElement(object key) { return (T)BaseGet(key); } } } 

这是上面引用的接口:

 namespace Abcd { public interface IConfigurationElement { object GetElementKey(); } }