2012-01-03 11 views
6

मेरे पास ऐप/web.config में पंजीकृत एक कस्टम कॉन्फ़िगरेशन अनुभाग है, चलो इसे MySection पर कॉल करें। मेरे पास नामक अनुभाग के अंदर ElementCollection तत्व है। तत्व संग्रह के अंदर मैं तत्वों को रखना चाहता हूं जो विभिन्न वर्गों द्वारा दर्शाए जाते हैं - विचार यह है कि ये कुछ सामान्य गुणों के साथ समान वर्ग हैं और कुछ उदाहरण के लिए विशिष्ट हैं।.NET कस्टम कॉन्फ़िगरेशन - क्या मेरे पास गैर-सजातीय तत्वों के साथ तत्व संग्रह हो सकते हैं?

यहाँ कुछ एक्सएमएल विन्यास उदाहरण है:

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

मेरी सरल उदाहरण में, सभी तत्वों को एक 'नाम' संपत्ति होनी चाहिए, कुछ भी एक 'मान' संपत्ति है, और अन्य एक 'प्रारूप' संपत्ति। यहां, मुझे Element1 और Element2 को दो अलग-अलग वर्गों द्वारा .NET रनटाइम में प्रदर्शित किया जाना चाहिए, जिसमें एक सामान्य आधार वर्ग है जो 'नाम' संपत्ति को परिभाषित करता है।

जहां तक ​​मैंने .NET कॉन्फ़िगरेशन में खोला है, मुझे यह धारणा मिली है कि एक तत्व संग्रह (जैसे 'माईलेमेंट्स') में समरूप तत्व (केवल एक प्रकार का) होना चाहिए। तो, मैं जो चाहता हूं उसे हासिल करना संभव हो सकता है - इसमें विभिन्न वर्गों के तत्व शामिल हैं। विचार अलग-अलग तत्व प्रकारों के लिए एक से अधिक तत्व संग्रह से बचने के लिए है और प्रत्येक कस्टम ConfigurationElement कार्यान्वयन के लिए सभी दोहराने वाले गुणों को नहीं लिखना है।

उत्तर

8

आप अपने एलिमेंट कोलेक्शन क्लास में OnDeserializeUnrecognizedElement विधि को ओवरराइड करके और पूर्व के लिए टैग नाम पर स्विच करके अपने एलिमेंट 1 और एलिमेंट 2 के प्रतिनिधित्व बनाकर इसे प्राप्त कर सकते हैं। लेकिन 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

अपने जवाब के लिए धन्यवाद। दरअसल, एक आम पूर्वज है जिसका अर्थ है कि मैं वैसे भी उपयोग करना चाहता हूं। कम से कम, मैं समान तत्वों के सामान्य गुणों का पुन: उपयोग करने की कोशिश कर रहा हूं, इसलिए आम पूर्वज उन्हें स्टोर कर सकता है और ठोस तत्वों के लिए कोड को भी कम कर सकता है :) –

संबंधित मुद्दे

 संबंधित मुद्दे