如何在自定義 configSection 中指定集合
我想要一個 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 等屬性,這裡並沒有真正探索),但我可以聲稱這是可行的 :)
此外,它不使用任何屬性。我討厭屬性——幸運的是,所有這些屬性都可以轉換為正確的程式碼。您可以使用其中一個(或兩者)。