2012-01-03 9 views
6

私はapp/web.configにカスタム設定セクションを登録しました。それをMySectionとしましょう。私はElementCollection要素をMyElementsというセクションの中に持っています。要素コレクションの中で、私は異なるクラスによって表される要素を持っていたいと思っています。これらのクラスは、いくつかの共通のプロパティとインスタンス固有のクラスです。ここで.NETカスタム設定 - 非同種要素の要素コレクションを持つことはできますか?

は、いくつかのxml構成例である:私の簡単な例では

<MySection> 
    <MyElements> 
    <Element1 name="someProp1" value="someValue" /> 
    <Element2 name="someProp2" format="{0}{1}" /> 
    </MyElements> 
</MySection> 

、すべての要素は「名前」プロパティを持っている必要があり、いくつかはまた、「の値」プロパティ、および他の「フォーマット」を持っていますプロパティ。 ここでは、Element1Element2を、「名前」プロパティを定義する共通基本クラスを持つ2つの異なるクラスによって.NETランタイムで表現したいと考えています。

私が.NETの設定を掘り下げている限り、私は要素コレクション(ここでは 'MyElements'など)に同種の要素(1つのタイプのみ)が含まれている必要があるという印象を受けました。それで、私が望むものを達成することは可能でしょうか。それは、それが異なるクラスの要素を含むようにします。この考え方は、異なる要素タイプに対して複数の要素コレクションを持つことと、すべてのカスタムのConfigurationElement実装のすべての繰り返しプロパティを記述しないことの両方を避けることです。

答えて

8

これを実現するには、ElementCollectionクラスのOnDeserializeUnrecognizedElementメソッドをオーバーライドし、exのタグ名をオンにしてElement1とElement2の表現を作成します。しかし、AFAIRの子要素は、共通の祖先から派生する必要があります。

としてのコレクションを定義します。

public class MyElementCollection : ConfigurationElementCollection 
{ 
    const string ELEMENT1 = "Element1"; 
    const string ELEMENT2 = "Element2"; 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new MyElement (this); 
    } 

    protected override object GetElementKey (ConfigurationElement element) 
    { 
     return ((MyElement)element).Key; 
    } 

    // This method called when framework sees unknown element tag 
    // inside the collection. You can choose to handle it yourself 
    // and return true, or return false to invoke default action 
    // (exception will be thrown). 
    protected override bool OnDeserializeUnrecognizedElement (string elementName, XmlReader reader) 
    { 
     if (elementName == ELEMENT1 || elementName == ELEMENT2 { 
      var myElement = new MyElement (this); 

      switch (elementName) { 
      case ELEMENT1: 
       myElement.Type = MyElementType.Element1; 
       break; 
      case ELEMENT2: 
       myElement.Type = MyElementType.Element2; 
       break; 
      } 

      myElement.DeserializeElementForConfig (reader, false); 
      BaseAdd (myElement); 

      return true; 
     } 

     return false; 
    } 
} 

と子要素:

public enum MyElementType 
{ 
    Element1, 
    Element2, 
} 

public class MyElement : ConfigurationElement 
{ 
    const string NAME = "name"; 
    const string VALUE = "value"; 
    const string FORMAT = "format"; 

    // keys should be unique, current collection count will do 
    // the trick without introducing artificial keys 
    public MyElement (ConfigurationElementCollection collection) 
    { 
     Key = collection.Count; 
    } 

    // note that this is not ConfigurationProperty 
    public int Key { get; private set; } 

    // note that this is not ConfigurationProperty 
    public MyElementType Type { get; set; } 

    [ConfigurationProperty(NAME)] 
    public string Name { 
     get { return (string)this [NAME]; } 
    } 

    [ConfigurationProperty(VALUE)] 
    public string Value { 
     get { return (string)this [VALUE]; } 
    } 

    [ConfigurationProperty(FORMAT)] 
    public string Format { 
     get { return (string)this [FORMAT]; } 
    } 

    // This is called when framework needs a copy of the element, 
    // but it knows only about properties tagged with ConfigurationProperty. 
    // We override this to copy our Key and Type, otherwise they will 
    // have default values. 
    protected override void Reset (ConfigurationElement parentElement) 
    { 
     base.Reset (parentElement); 

     var myElement = (MyElement)parentElement; 
     Key = myElement.Key; 
     Type = myElement.Type; 
    } 

    // original ConfigurationElement have this protected, 
    // redeclaring as protected internal to call it from collection class 
    protected internal void DeserializeElementForConfig (XmlReader reader, bool serializeCollectionKey) 
    { 
     DeserializeElement (reader, serializeCollectionKey); 
    } 
} 
+0

は、あなたの答えをいただき、ありがとうございます。実際、共通の祖先は、とにかく私が使用することを意味しています。少なくとも、私は同様の要素の共通のプロパティを再利用しようとしているので、共通の祖先はそれらを格納し、具体的な要素のコードも減らすことができます:) –

関連する問題