将自定义属性添加到app.config中的Custom Provider Configuration Section

我正在关注如何在.NET中创建Provider框架的这篇伟大文章

基本上,本文大致解释了如何最终得到如下配置文件:

  

其中元素允许您定义提供者。

但是,我想知道如何使用自定义属性扩展add条目。

例如:

    

任何帮助将不胜感激。

这是我终于找到的。 这是一个非常具体的问题,关于使用更多属性扩展元素以及在实现Provider Framework时如何处理它们。 关于自定义配置部分的所有答案都可以,但不能解决原始问题。

如果您需要实现自定义提供程序(如MembershipProvider ,但出于自己的目的,您需要阅读本文: 创建自己的提供程序框架

这是很好的阅读。 现在,如果您需要使用自己的属性扩展元素,那么您需要更改以下内容…

1)接下来是文章中讨论的代码(可能有一些改编):

 using System; using System.Configuration; using System.Collections.Generic; using System.Linq; using System.Text; using System.Configuration.Provider; using System.Collections.Specialized; public abstract class DataProvider : ProviderBase { // Define the methods to be used by the provider. These are custom methods to your own provider. public abstract void Get(); public abstract void Delete(); } public class DataProviderCollection : ProviderCollection { } //The name is typically the same as the abstract class, minus the Provider part. Sticking to our (fake) example. we'd have a static class called Data. public static class Data { private static bool _isInitialized = false; private static DataProvider _provider; public static DataProvider Provider { get { Initialize(); return _provider; } } private static DataProviderCollection _providers; public static DataProviderCollection Providers { get { Initialize(); return _providers; } } private static void Initialize() { DataProviderConfigurationSection dataConfig = null; if (!_isInitialized) { // get the configuration section for the feature dataConfig = (DataProviderConfigurationSection)ConfigurationManager.GetSection("data"); if (dataConfig == null) { throw new ConfigurationErrorsException("Data is not configured to be used with this application"); } _providers = new DataProviderCollection(); // use the ProvidersHelper class to call Initialize() on each provider ProvidersHelper.InstantiateProviders(dataConfig.Providers, _providers, typeof(DataProvider)); // set a reference to the default provider _provider = _providers[dataConfig.DefaultProvider] as DataProvider; _isInitialized = true; } } public static void Get() { Initialize(); if (_provider != null) { _provider.Get(); } } public static void Delete() { Initialize(); if (_provider != null) { _provider.Delete(); } } } public class MyDataProvider : DataProvider { public override void Get() { // Get Code } public override void Delete() { // Delete Code } } public class DataProviderConfigurationSection : ConfigurationSection { public DataProviderConfigurationSection() { _defaultProvider = new ConfigurationProperty("defaultProvider", typeof(string), null); _providers = new ConfigurationProperty("providers", typeof(ProviderSettingsCollection), null); _properties = new ConfigurationPropertyCollection(); _properties.Add(_providers); _properties.Add(_defaultProvider); } private readonly ConfigurationProperty _defaultProvider; [ConfigurationProperty("defaultProvider")] public string DefaultProvider { get { return (string)base[_defaultProvider]; } set { base[_defaultProvider] = value; } } private readonly ConfigurationProperty _providers; [ConfigurationProperty("providers")] public ProviderSettingsCollection Providers { get { return (ProviderSettingsCollection)base[_providers]; } } private ConfigurationPropertyCollection _properties; protected override ConfigurationPropertyCollection Properties { get { return _properties; } } } public static class ProvidersHelper { private static Type providerBaseType = typeof(ProviderBase); ///  /// Instantiates the provider. ///  /// The settings. /// Type of the provider to be instantiated. ///  public static ProviderBase InstantiateProvider(ProviderSettings providerSettings, Type providerType) { ProviderBase base2 = null; try { string str = (providerSettings.Type == null) ? null : providerSettings.Type.Trim(); if (string.IsNullOrEmpty(str)) { throw new ArgumentException("Provider type name is invalid"); } Type c = Type.GetType(str, true, true); if (!providerType.IsAssignableFrom(c)) { throw new ArgumentException(String.Format("Provider must implement type {0}.", providerType.ToString())); } base2 = (ProviderBase)Activator.CreateInstance(c); NameValueCollection parameters = providerSettings.Parameters; NameValueCollection config = new NameValueCollection(parameters.Count, StringComparer.Ordinal); foreach (string str2 in parameters) { config[str2] = parameters[str2]; } base2.Initialize(providerSettings.Name, config); } catch (Exception exception) { if (exception is ConfigurationException) { throw; } throw new ConfigurationErrorsException(exception.Message, providerSettings.ElementInformation.Properties["type"].Source, providerSettings.ElementInformation.Properties["type"].LineNumber); } return base2; } public static void InstantiateProviders(ProviderSettingsCollection providerSettings, ProviderCollection providers, Type type) { foreach (ProviderSettings settings in providerSettings) { providers.Add(ProvidersHelper.InstantiateProvider(settings, type)); } } } 

2)这是您用于上述代码的配置文件:

    

3)现在,您需要修改以便使用读取配置文件中元素中的属性。

  public abstract class DataProvider : ProviderBase { public string MyAttribute1 { get; set; } public string MyAttribute2 { get; set; } public string MyAttribute3 { get; set; } // Define the methods to be used by the provider. These are custom methods to your own provider. public abstract void Get(); public abstract void Delete(); public override void Initialize(string name, NameValueCollection config) { MyAttribute1 = config["MyAttribute1"]; MyAttribute2 = config["MyAttribute2"]; MyAttribute3 = config["MyAttribute3"]; base.Initialize(name, config); } } 

4)配置文件如下所示:

    

作为奖励,这里有一个unit testing来validation它的工作原理:

 [TestMethod] public void RunMyDataProviderTest() { DataProvider dataProvider = Data.Provider; Assert.IsInstanceOfType(dataProvider, typeof(MyDataProvider)); Assert.AreEqual(dataProvider.MyAttribute1, "MyValue1"); Assert.AreEqual(dataProvider.MyAttribute2, "MyValue2"); } 

您可以使用ConfigurationProperty和ProviderBase

喜欢:

  

c#代码:

 ///  /// counting ///  public class CountingStrategyConfigurationElement : StrategyConfigurationElement { ///  /// constructor ///  public CountingStrategyConfigurationElement() { } ///  /// constructor ///  public CountingStrategyConfigurationElement(string name) : base(name) { } ///  /// The max number of requests ///  [ConfigurationProperty("maxRequestNumber", IsKey = false, IsRequired = true)] public int MaxRequestNumber { get { return (int)this["maxRequestNumber"]; } set { this["maxRequestNumber"] = value; } } ///  /// Counting request in this range of time ///  [ConfigurationProperty("countingTimeRange", IsKey = false, IsRequired = true)] public TimeSpan CountingTimeRange { get { return (TimeSpan)this["countingTimeRange"]; } set { this["countingTimeRange"] = value; } } ///  /// Counting Time Accuracy ///  [ConfigurationProperty("countingTimeAccuracy", IsKey = false, IsRequired = true)] public TimeSpan CountingTimeAccuracy { get { return (TimeSpan)this["countingTimeAccuracy"]; } set { this["countingTimeAccuracy"] = value; } } } 

您需要创建自定义ConfigurationSection实现 ,这将允许您创建自己提供的自定义配置树。