.NET4

2011-08-15 10 views
9

में संग्रह के साथ सरल कस्टम कॉन्फ़िगरेशन अनुभाग। मैं .NET4 अनुप्रयोग के लिए एक बहुत ही सरल कस्टम कॉन्फ़िगरेशन अनुभाग लिखने की कोशिश कर रहा हूं।.NET4

<configuration> 
    <configSections> 
    <section name="myServices" type="My.ConfigSection, My.Assembly" /> 
    </configSections> 
    <myServices> 
    <add name="First" /> 
    <add name="Second" /> 
    </myServices> 
</configuration> 

हालांकि, मैं एक ConfigurationErrorsException मिलती रहती है: मेरा लक्ष्य यह है 'न पहचाना गया तत्व' जोड़ें '' जब मैं ConfigurationManager.GetSection("myServices") कहते हैं। मैं थोड़ी देर के लिए इस पर घूर रहा हूं लेकिन अभी तक यह पता नहीं लगाया है कि मैं क्या गलत कर रहा हूं। नीचे मेरा कोड है। यह तीन वर्ग है: ConfigSection, MyServiceSettingsCollection और MyServiceSettings

पहले कक्षा जो संपूर्ण कॉन्फ़िगरेशन अनुभाग का प्रतिनिधित्व करती है। इसमें MyServiceSettingsCollection का नामहीन डिफ़ॉल्ट संग्रह है। IsDefaultCollection संपत्ति मुझे रूट तत्व से सीधे मेरे संग्रह में 'जोड़ने' की अनुमति देनी चाहिए।

public sealed class ConfigSection : ConfigurationSection 
{ 
    private static readonly ConfigurationProperty _propMyServices; 

    private static readonly ConfigurationPropertyCollection _properties; 

    public static ConfigSection Instance { get { return _instance; } } 

    static ConfigSection() 
    { 
    _propMyServices = new ConfigurationProperty(
      null, typeof(MyServiceSettingsCollection), null, 
      ConfigurationPropertyOptions.IsDefaultCollection); 
    _properties = new ConfigurationPropertyCollection { _propMyServices }; 
    } 

    [ConfigurationProperty("", IsDefaultCollection = true)] 
    public MyServiceSettingsCollection MyServices 
    { 
    get { return (MyServiceSettingsCollection) base[_propMyServices]; } 
    set { base[_propMyServices] = value; } 
    } 

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

अगला, संग्रह वर्ग स्वयं। यह AddRemoveClearMap प्रकार है।

[ConfigurationCollection(typeof(MyServiceSettings), 
    CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] 
public sealed class MyServiceSettingsCollection : ConfigurationElementCollection 
{ 
    public MyServiceSettings this[int index] 
    { 
    get { return (MyServiceSettings) BaseGet(index); } 
    set 
    { 
     if (BaseGet(index) != null) { BaseRemoveAt(index); } 
     BaseAdd(index, value); 
    } 
    } 

    public new MyServiceSettings this[string key] 
    { 
    get { return (MyServiceSettings) BaseGet(key); } 
    } 

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

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

और अंत में संग्रह में तत्वों के लिए एक कक्षा। अभी के लिए, इस वर्ग में एक संपत्ति है लेकिन बाद में और अधिक होगा (जो मुझे NameValueSectionHandler का उपयोग करने से रोकता है)।

public class MyServiceSettings : ConfigurationElement 
{ 
    private static readonly ConfigurationProperty _propName; 

    private static readonly ConfigurationPropertyCollection properties; 

    static MyServiceSettings() 
    { 
    _propName = new ConfigurationProperty("name", typeof(string), null, null, 
              new StringValidator(1), 
              ConfigurationPropertyOptions.IsRequired | 
              ConfigurationPropertyOptions.IsKey); 
    properties = new ConfigurationPropertyCollection { _propName }; 
    } 

    [ConfigurationProperty("name", DefaultValue = "", 
     Options = ConfigurationPropertyOptions.IsRequired | 
        ConfigurationPropertyOptions.IsKey)] 
    public string Name 
    { 
     get { return (string) base[_propKey]; } 
     set { base[_propKey] = value; } 
    } 

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

उत्तर

11

ठीक है देखते हैं कि यह

[ConfigurationProperty("urls", IsDefaultCollection = false)] 
    [ConfigurationCollection(typeof(UrlsCollection), 
     AddItemName = "add", 
     ClearItemsName = "clear", 
     RemoveItemName = "remove")] 

को कुछ इसी तरह याद कर रहे हैं लगता है, मैं मालूम होता है यादृच्छिक समाधान मिल जाने। इसके बजाय इस की:

[ConfigurationProperty("", IsDefaultCollection = true)] 
public ProvisiorServiceSettingsCollection ProvisiorServices 
{ ... } 

आप उपयोग करना चाहिए:

[ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)] 
public ProvisiorServiceSettingsCollection ProvisiorServices 
{ ... } 

कोई विचार क्या अंतर दोनों के बीच है। मेरे लिए, वे बहुत ही समान दिखते हैं ... या कम से कम, कोई सुझाव नहीं है कि किसी को दूसरे पर क्यों पसंद किया जाता है।

+0

लेकिन यह जानना अच्छा है कि यह कैसे काम करता है - अगले सप्ताह में कुछ हासिल करने के समान होगा, इसलिए धन्यवाद :-) – Yahia

+0

यह अजीब बात है। दोनों 'IsDefaultCollection' और' विकल्प 'मेरे लिए काम करते हैं। लेकिन संपत्ति के नाम के लिए खाली स्ट्रिंग रखना अनिवार्य प्रतीत होता है। –

+0

ConfigurationPropertyAttribute.cs के संदर्भ स्रोत को देखते हुए, IsDefaultCollection प्रॉपर्टी विकल्प फ़्लैग प्रॉपर्टी पर केवल एक रैपर है - http://referencesource.microsoft.com/#System.Configuration/System/Configuration/ConfigurationPropertyAttribute.cs,62 –

3

यह आप अधिक जानकारी के लिए http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx

+0

पहले से ही कोशिश की है और यह काम नहीं किया है। मुझे जवाब मिला, जल्द ही इसे जोड़ देगा। –

+0

दूसरा विकल्प - http://www.sitepoint.com/forums/net-141/problem-custom-config-section-419546.html – Yahia

+0

पर बहुत पिछली प्रविष्टि देखें, उस फ़ोरम पोस्ट को भी देखा है। इस सवाल से पूछने से पहले, मैंने जवाब खोजने के लिए पहले से ही अपने सभी Google कौशल का उपयोग किया है :) –

3

जब से मैं इस पर समय का एक अच्छा राशि खर्च की, सोचा था कि मैं एक असली दुनिया उदाहरण मैं सिर्फ इस में लागू जोड़ा जाने के लिए प्रतिबद्ध: https://github.com/rhythmagency/formulate/commit/4d2a95e1a82eb6b3500ab0869b8f8b15bd3deaa9

यहाँ मेरी web.config के लिए मेरा लक्ष्य था (जो मैं कर रहा था प्राप्त करने के लिए):

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <sectionGroup name="formulateConfiguration"> 
     <section name="templates" type="formulate.app.Configuration.TemplatesConfigSection, formulate.app" requirePermission="false"/> 
    </sectionGroup> 
    </configSections> 
    <formulateConfiguration> 
    <templates> 
     <template name="Responsive" path="~/Views/Formulate/Responsive.Bootstrap.Angular.cshtml" /> 
    </templates> 
    </formulateConfiguration> 
</configuration> 

यह उच्चतम स्तर के "टेम्पलेट्स" विन्यास खंड के लिए वर्ग है:

namespace formulate.app.Configuration 
{ 

    // Namespaces. 
    using System.Configuration; 


    /// <summary> 
    /// A configuration section for Formulate templates. 
    /// </summary> 
    public class TemplatesConfigSection : ConfigurationSection 
    { 

     #region Properties 

     /// <summary> 
     /// The templates in this configuration section. 
     /// </summary> 
     [ConfigurationProperty("", IsDefaultCollection = true)] 
     [ConfigurationCollection(typeof(TemplateCollection), AddItemName = "template")] 
     public TemplateCollection Templates 
     { 
      get 
      { 
       return base[""] as TemplateCollection; 
      } 
     } 

     #endregion 

    } 

} 

यहाँ नीचे अगले स्तर, संग्रह है वर्ग:

namespace formulate.app.Configuration 
{ 

    // Namespaces. 
    using System.Configuration; 


    /// <summary> 
    /// A collection of templates from the configuration. 
    /// </summary> 
    [ConfigurationCollection(typeof(TemplateElement))] 
    public class TemplateCollection : ConfigurationElementCollection 
    { 

     #region Methods 

     /// <summary> 
     /// Creates a new template element. 
     /// </summary> 
     /// <returns>The template element.</returns> 
     protected override ConfigurationElement CreateNewElement() 
     { 
      return new TemplateElement(); 
     } 


     /// <summary> 
     /// Gets the key for an element. 
     /// </summary> 
     /// <param name="element">The element.</param> 
     /// <returns>The key.</returns> 
     protected override object GetElementKey(ConfigurationElement element) 
     { 
      return (element as TemplateElement).Name; 
     } 

     #endregion 

    } 

} 

और यहाँ गहरे स्तर वर्ग (व्यक्तिगत टेम्पलेट्स) है:

namespace formulate.app.Configuration 
{ 

    // Namespaces. 
    using System.Configuration; 


    /// <summary> 
    /// A "template" configuration element. 
    /// </summary> 
    public class TemplateElement : ConfigurationElement 
    { 

     #region Constants 

     private const string DefaultPath = "~/*Replace Me*.cshtml"; 

     #endregion 


     #region Properties 

     /// <summary> 
     /// The name of the template. 
     /// </summary> 
     [ConfigurationProperty("name", IsRequired = true)] 
     public string Name 
     { 
      get 
      { 
       return base["name"] as string; 
      } 
      set 
      { 
       this["name"] = value; 
      } 
     } 


     /// <summary> 
     /// The path to this template. 
     /// </summary> 
     /// <remarks> 
     /// Should start with "~" and end with ".cshtml". 
     /// </remarks> 
     [ConfigurationProperty("path", IsRequired = true, DefaultValue = DefaultPath)] 
     [RegexStringValidator(@"^~.*\.[cC][sS][hH][tT][mM][lL]$")] 
     public string Path 
     { 
      get 
      { 
       var result = base["path"] as string; 
       return result == DefaultPath ? null : result; 
      } 
      set 
      { 
       this["path"] = value; 
      } 
     } 

     #endregion 

    } 

} 

मेरे लिए महत्वपूर्ण बिट सही पर ConfigurationPropertyAttribute में रिक्त स्ट्रिंग और सेटिंग IsDefaultCollection के लिए किया गया था।वैसे, मुझे लगता है कि इस तरह दिखता है एक बाहरी फ़ाइल में मेरी config डाल:

<?xml version="1.0" encoding="utf-8" ?> 
<templates> 
    <template name="Responsive" path="~/Views/Formulate/Responsive.Bootstrap.Angular.cshtml" /> 
</templates> 

और उस मामले में, मेरे web.config इस तरह दिखता है:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <sectionGroup name="formulateConfiguration"> 
     <section name="templates" type="formulate.app.Configuration.TemplatesConfigSection, formulate.app" requirePermission="false"/> 
    </sectionGroup> 
    </configSections> 
    <formulateConfiguration> 
    <templates configSource="config\Formulate\templates.config"/> 
    </formulateConfiguration> 
</configuration> 

लगा कि मैं उल्लेख करें कि यदि कोई और इसे बाहरी फ़ाइल में जोड़ने का प्रयास कर रहा है (यह कुछ हद तक अंतर्ज्ञानी है कि बाहरी फ़ाइल में रूट-स्तरीय आइटम web.config से बाह्य तत्व के समान है)।

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