Dot-Net

如何在自定義 configSection 中指定集合

  • February 9, 2015

我想要一個 xml 配置文件,如下所示:

<?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 類之間的相互作用?

我在網上找到了這個教程,但它會在外掛中引入一個圍繞使用集合的元素,我不需要這個。

是我到目前為止所擁有的,但它並不完全正確

如果 MyApp.PluginsConfiguration 是 ConfigurationSection,那麼您可以定義一個繼承自 ConfigurationElementCollection 的新類,並使新類成為 MyApp.PluginsConfiguration 的 ConfigurationProperty

查看本文以獲取有關這些類型的一些深入資訊。我還寫了關於嵌套屬性的部落格,但不是專門針對集合的。

**編輯:**這裡有一些程式碼。給出的是 web.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();

基本上我們有一個處理外掛元素的配置部分。在此,我們指定一個 ConfigurationElementCollection 屬性並將其聲明為預設集合(理論上您可以在一個根節點下擁有多個不同的集合)。

PluginsElementCollection 實現了 ConfigurationElementCollection。ElementName 必須是標籤的名稱,在我們的例子中是“use”。此外,GetElementKey 需要被覆蓋,並且應該返回一個在條目中唯一的屬性。

然後 PluginsElement 實現了單次使用標籤。我們只定義一個屬性:AssemblyName,它映射到程序集屬性。

我並沒有聲稱完全理解所有這些(特別是 ConfigurationElementCollection 以及它的各種 BaseAdd、BaseGet 等屬性,這裡並沒有真正探索),但我可以聲稱這是可行的 :)

此外,它不使用任何屬性。我討厭屬性——幸運的是,所有這些屬性都可以轉換為正確的程式碼。您可以使用其中一個(或兩者)。

引用自:https://stackoverflow.com/questions/2002715