2012-01-12 26 views
25

cho cấu hình như saucách có thuộc tính tùy chỉnh trong ConfigurationElementCollection?

<MyCollection default="one"> 
    <entry name="one" ... other attrubutes /> 
    ... other entries 
</MyCollection> 

khi thực hiện một MyCollection, những gì tôi nên làm cho "mặc định" thuộc tính?

+0

việc kiểm tra này ra: https://stackoverflow.com/questions/43037691/design-to-implement-a-wrapper-for-configurationsection-net-class –

Trả lời

49

Hãy giả sử bạn có tập tin .config này:

<configuration> 
    <configSections> 
     <section name="mySection" type="ConsoleApplication1.MySection, ConsoleApplication1" /> // update type & assembly names accordingly 
    </configSections> 

    <mySection> 
     <MyCollection default="one"> 
      <entry name="one" /> 
      <entry name="two" /> 
     </MyCollection> 
    </mySection> 
</configuration> 

Sau đó, với mã này:

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"]; 
     } 
    } 
} 

bạn có thể đọc cấu hình với các thuộc tính 'mặc định', như thế này:

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

Điều này sẽ xuất ra "một"

+1

AddItemName = "entry", đó là chính xác những gì Tôi muốn! – Xinan

5

Tôi không biết liệu có thể có giá trị mặc định trong ConfigurationElementCollection hay không. (nó không thấy có bất kỳ thuộc tính nào cho giá trị mặc định).

Tôi đoán bạn phải tự mình triển khai điều này. Hãy xem ví dụ bên dưới.

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; } 
    } 
} 

Dưới đây là cấu hình XML:

<myConfig currentRepository="SQL2008"> 
    <repositories> 
     <add key="SQL2008" value="abc"/> 
     <add key="Oracle" value="xyz"/> 
    </repositories> 
    </myConfig> 

Và sau đó, tại mã của bạn, bạn truy cập vào mục mặc định bằng cách sử dụng sau đây:

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

Tất nhiên, lớp MyConfig có thể ẩn các chi tiết truy cập các thuộc tính Repositories và CurrentRepository. Bạn có thể có một thuộc tính được gọi là DefaultRepository (của kiểu Repository) trong lớp MyConfig để trả về điều này.

0

Nếu bạn muốn genericize nó, điều này sẽ giúp:

using System.Configuration; 

namespace Abcd 
{ 
    // Generic implementation of ConfigurationElementCollection. 
    [ConfigurationCollection(typeof(ConfigurationElement))] 
    public class ConfigurationElementCollection<T> : 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); 
    } 
    } 
} 

Dưới đây là giao diện tham chiếu ở trên:

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

Đây có thể là hơi muộn nhưng có thể hữu ích cho người khác.

Có thể nhưng với một số sửa đổi.

  • ConfigurationElementCollection kế thừa ConfigurationElement như vậy "this [string]" có sẵn trong ConfigurationElement.

  • Thông thường khi ConfigurationElementCollection được kế thừa và triển khai trong một lớp khác, "chuỗi này ["] được ẩn với "mới [chuỗi này]".

  • Một cách để có được xung quanh nó là để tạo ra một thực hiện này [] như "này [string, string]"

Xem ví dụ dưới đây.

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; } 
    } 
} 
Các vấn đề liên quan