2010-01-04 4 views
8

मैं इस प्रकार एक xml कॉन्फ़िग फ़ाइल करना चाहते हैं:एक कस्टम configSection में एक संग्रह निर्दिष्ट करने के लिए कैसे

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
<configSections> 
    <section name="plugins" type="MyApp.PluginsConfiguration, MyApp"/> 
</configSections> 

<plugins> 
    <use assembly="MyApp.Plugin1.dll" /> 
    <use assembly="MyApp.Plugin2.dll" /> 
</plugins> 
</configuration> 

वास्तव में किस प्रकार मैं अपने कोड में PluginsConfigurations, UsePluginCollection, और UsePlugin वर्गों के बीच परस्पर क्रिया की व्यवस्था करते हैं ?

मैं this tutorial ऑनलाइन पाया लेकिन यह करने वाले प्लग इन उपयोग संग्रह चारों ओर से घेरे के अंदर एक तत्व को पेश होगा और मैं इस जरूरत नहीं है।

This क्या मैं अब तक है, लेकिन है यह सही काफी नहीं

उत्तर

16

तो MyApp.PluginsConfiguration एक ConfigurationSection है, तो आप एक नया वर्ग है कि ConfigurationElementCollection से विरासत को परिभाषित करने और के बारे में कुछ में गहराई से जानकारी के लिए नया वर्ग MyApp.PluginsConfiguration

चेक this article के ConfigurationProperty कर सकते हैं उन प्रकारों। मैं भी blogged about नेस्टेड गुण है, लेकिन विशेष रूप से नहीं संग्रहों के लिए।

संपादित करें: कुछ कोड के साथ यहाँ। यह वेब.config में दिया गया है:

<configSections> 
    <section name="plugins" 
      type="WebApplication1.PluginsConfiguration, WebApplication1"/> 
</configSections> 
<plugins> 
    <use assembly="MyApp.Plugin1.dll"/> 
    <use assembly="MyApp.Plugin2.dll"/> 
</plugins> 

ऐसा करने के लिए कक्षाएं यहां दी गई हैं। ध्यान दें कि शायद NullReferenceExceptions जिन्हें संभालने की आवश्यकता होगी।

namespace WebApplication1 
{ 
    public class PluginsConfiguration : ConfigurationSection 
    { 
     private static ConfigurationPropertyCollection properties; 
     private static ConfigurationProperty propPlugins; 

     static PluginsConfiguration() 
     { 
      propPlugins = new ConfigurationProperty(null, typeof(PluginsElementCollection), 
                  null, 
                  ConfigurationPropertyOptions.IsDefaultCollection); 
      properties = new ConfigurationPropertyCollection { propPlugins }; 
     } 

     protected override ConfigurationPropertyCollection Properties 
     { 
      get 
      { 
       return properties; 
      } 
     } 

     public PluginsElementCollection Plugins 
     { 
      get 
      { 
       return this[propPlugins] as PluginsElementCollection; 
      } 
     } 
    } 

    public class PluginsElementCollection : ConfigurationElementCollection 
    { 
     public PluginsElementCollection() 
     { 
      properties = new ConfigurationPropertyCollection(); 
     } 

     private static ConfigurationPropertyCollection properties; 

     protected override ConfigurationPropertyCollection Properties 
     { 
      get 
      { 
       return properties; 
      } 
     } 

     public override ConfigurationElementCollectionType CollectionType 
     { 
      get 
      { 
       return ConfigurationElementCollectionType.BasicMap; 
      } 
     } 

     protected override string ElementName 
     { 
      get 
      { 
       return "use"; 
      } 
     } 

     protected override ConfigurationElement CreateNewElement() 
     { 
      return new PluginsElement(); 
     } 

     protected override object GetElementKey(ConfigurationElement element) 
     { 
      var elm = element as PluginsElement; 
      if (elm == null) throw new ArgumentNullException(); 
      return elm.AssemblyName; 
     } 
    } 

    public class PluginsElement : ConfigurationElement 
    { 
     private static ConfigurationPropertyCollection properties; 
     private static ConfigurationProperty propAssembly; 

     protected override ConfigurationPropertyCollection Properties 
     { 
      get 
      { 
       return properties; 
      } 
     } 

     public PluginsElement() 
     { 
      propAssembly = new ConfigurationProperty("assembly", typeof(string), 
                  null, 
                  ConfigurationPropertyOptions.IsKey); 
      properties = new ConfigurationPropertyCollection { propAssembly }; 
     } 

     public PluginsElement(string assemblyName) 
      : this() 
     { 
      AssemblyName = assemblyName; 
     } 

     public string AssemblyName 
     { 
      get 
      { 
       return this[propAssembly] as string; 
      } 
      set 
      { 
       this[propAssembly] = value; 
      } 
     } 
    } 
} 

और यह तक पहुँचने के लिए, इस कोड स्निपेट की मदद करनी चाहिए:

 var cfg = WebConfigurationManager.GetWebApplicationSection("plugins") as PluginsConfiguration; 
     var sb = new StringBuilder(); 
     foreach(PluginsElement elem in cfg.Plugins) 
     { 
      sb.AppendFormat("{0}<br/>", elem.AssemblyName); 
     } 
     testLabel.Text = sb.ToString(); 

असल में हम एक ConfigurationSection कि प्लगइन्स तत्व संभालती है। इस में, हम एक ConfigurationElementCollection संपत्ति निर्दिष्ट और डिफ़ॉल्ट संग्रह (आप सिद्धांत में कर सकता है एक रूट नोड के अंतर्गत कई विभिन्न संग्रह है) के रूप में यह घोषणा करते हैं।

PluginsElementCollection ConfigurationElementCollection लागू करता है। हमारे मामले में "उपयोग" में एलिमेंटनाम को टैग का नाम होना चाहिए। साथ ही, GetElementKey को ओवरराइड करने की आवश्यकता है और प्रविष्टियों के बीच अद्वितीय विशेषता को वापस कर देना चाहिए।

प्लगइन्स एलिमेंट तब एक एकल उपयोग टैग लागू करता है। हम केवल एक संपत्ति को परिभाषित करते हैं: असेंबलीनाम, जिसे असेंबली-एट्रिब्यूट में मैप किया गया है।

मैं पूरी तरह से यह सब समझने के लिए दावा नहीं करते हैं (विशेष रूप से ConfigurationElementCollection और यह विभिन्न BaseAdd, BaseGet आदि गुण वास्तव में यहाँ का पता लगाया है नहीं कर रहे हैं), लेकिन मैं दावा कर सकते हैं कि इस काम करता है :)

इसके अलावा, यह किसी भी विशेषताओं का उपयोग नहीं करता है। मुझे गुणों से नफरत है - सौभाग्य से, इन सभी विशेषताओं को उचित कोड में परिवर्तित किया जा सकता है। आप एक या दूसरे (या दोनों) का उपयोग कर सकते हैं।

+0

यदि आप चाहें तो System.Web.Configuration.CustomErrorsSection और अन्य का उपयोग कर देखें या तो परावर्तक या डिबगिंग सर्वर। यह देखते हुए कि माइक्रोसॉफ्ट इन्हें कैसे लागू करता है (आईएमएचओ बल्कि जटिल) वर्ग अच्छी अंतर्दृष्टि देता है। –

+0

एमएसडीएन दस्तावेज़ों से बेहतर! thanx – Aliostad

+0

एमएसडीएन की तुलना में निश्चित रूप से बेहतर है। बहुत धन्यवाद! – Sergejs

4

ट्यूटोरियल के आधार पर, आप आसानी से एक एक्सएमएल विन्यास इस प्रकार बना सकते हैं:

<MyApp> 
    <Plugins> 
    <add assembly="MyApp.Plugin1.dll" /> 
    <add assembly="MyApp.Plugin2.dll" /> 
    </Plugins> 
</MyApp> 

कौन सा मैं पूरी तरह से स्वीकार्य पाते हैं। क्या कोई कारण यह अस्वीकार्य होगा?

संपादित करें:

मैं कैसे वास्तव में ट्यूटोरियल के साथ ऐसा करने में यकीन नहीं है। आप मध्यवर्ती तत्व किसी प्रकार की आवश्यकता होगी (ट्यूटोरियल की तरह "कार्रवाई" है) - जॉर्ज Mauer

ठीक है, इस आकार के लिए पर प्रयास करें। के बाद से मैं प्रतिलिपि करने/चिपकाने/संपादन कुछ कोड मुझे लगता है कि आप क्या चाहते हैं करता है प्रयोग किया जाता रहा हूँ मैं कुछ लेखन त्रुटि हो सकती है, लेकिन यह एक्सएमएल मैं ऊपर परिभाषित के साथ काम करना चाहिए।

public sealed class MyAppConfiguration : ConfigurationSection 
{ 
    public const string MyAppConfigurationTagName = "MyApp"; 
    [ConfigurationProperty(MyAppConfigurationTagName, IsRequired = true)] 
    public PluginConfigurationCollection Plugins 
    { 
     get 
     { 
      return this[MyAppConfigurationTagName] as PluginConfigurationCollection; 
     } 
     set 
     { 
      this[MyAppConfigurationTagName] = value; 
     } 
    } 
} 

public sealed class PluginConfigurationItem : ConfigurationElement 
{ 
    // repeat this pattern for each additional attribute you want in the <add /> tag. 
    // Only the assembly="foo.dll" portion is defined in this class, and is accessed 
    // via the AssemblyName property. 
    public const string AssemblyPropertyName = "assembly"; 
    [ConfigurationProperty(AssemblyPropertyName, IsRequired = true, IsKey = true)] 
    public string AssemblyName 
    { 
     get 
     { 
      return this[AssemblyPropertyName] as string; 
     } 
     set 
     { 
      this[AssemblyPropertyName] = value; 
     } 
    } 
} 

public class PluginConfigurationCollection : ConfigurationElementCollection, IEnumerable<PluginConfigurationItem> 
{ 
    public const string PluginsElementName = "Plugins"; 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new PluginConfigurationItem(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((PluginConfigurationItem)element).AssemblyName; 
    } 

    protected override string ElementName 
    { 
     get 
     { 
      return PluginsElementName; 
     } 
    } 

    // this is extraneous, but I find it very useful for enumerating over a configuration collection in a type-safe manner. 
    #region IEnumerable<PluginConfigurationItem> Members 

    public new IEnumerator<PluginConfigurationItem> GetEnumerator() 
    { 
     foreach(PluginConfigurationItem item in (this as IEnumerable)) 
     { 
      yield return item; 
     } 
    } 

    #endregion 
} 
+0

मुझे यकीन नहीं है कि ट्यूटोरियल के साथ इसे कैसे करना है। आपको कुछ प्रकार के इंटरमीडिएट तत्व की आवश्यकता होगी (जैसे ट्यूटोरियल में "क्रियाएं" हैं) –

+1

इस दृष्टिकोण में, आप आंतरिक नाम ValueSectionHandler का उपयोग करने में सक्षम होना चाहिए: http://msdn.microsoft.com/en-us/library/system। config.namevaluesectionhandler.aspx - क्षमा करें, बिल्कुल नहीं पता कि कैसे (मैं ईमानदार से अपना खुद का रोल करूंगा), लेकिन Google यहां मदद करेगा :) –

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

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