【问题标题】:Adding custom attributes to Custom Provider Configuration Section in app.config将自定义属性添加到 app.config 中的自定义提供程序配置部分
【发布时间】:2012-02-29 13:06:15
【问题描述】:

我正在关注 .NET 中 how to create a Provider framework 上的这篇精彩文章

基本上,这篇文章详细解释了如何得到如下配置文件:

   <configuration>
     <configSections>
        <section name="data" type="DataProviderConfigurationSection" />
      </configSections>
      <data defaultProvider="MyDataProvider">
         <providers>
            <add name="MydataProvider" type="MyDataProvider"  />
         </providers>
      </data>
   </configuration>

&lt;add/&gt; 元素允许您定义提供者。

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

例如:

<providers>
  <add name="MydataProvider" type="MyDataProvider" myProperty="myValue" myProperty2="myValue2" ... />
</providers>

任何帮助将不胜感激。

【问题讨论】:

    标签: c# provider configurationsection


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      喜欢:

      <add name="countingCfg" maxRequestNumber="10" countingTimeRange="00:00:10" countingTimeAccuracy="00:00:02" />
      

      ?

      c#代码:

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

      【讨论】:

        【解决方案3】:

        您需要创建一个custom ConfigurationSection implementation,这将允许您创建一个您提供的自定义配置树。

        【讨论】:

          【解决方案4】:

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

          如果你需要实现一个自定义的Provider,比如MembershipProvider,但是为了你自己的目的,你绝对需要阅读这篇文章:Creating Your Own Provider Framework

          这是一本优秀的读物。现在,如果您需要使用自己的属性扩展元素,则需要更改以下内容...

          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);
          
                  /// <summary>
                  /// Instantiates the provider.
                  /// </summary>
                  /// <param name="providerSettings">The settings.</param>
                  /// <param name="providerType">Type of the provider to be instantiated.</param>
                  /// <returns></returns>
                  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) 这是您用于上述代码的配置文件:

            <configuration>
              <configSections>
                <section name="data" type="DataProviderConfigurationSection" />
              </configSections>
              <data defaultProvider="MyDataProvider">
                <providers>
                  <add name="MydataProvider" type="MyDataProvider"  />
                </providers>
              </data>
            </configuration>
          

          3) 现在,您需要修改以下内容才能使用读取配置文件中&lt;add&gt; 元素中的属性。

              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) 配置文件如下所示:

            <configuration>
              <configSections>
                <section name="data" type="DataProviderConfigurationSection" />
              </configSections>
              <data defaultProvider="MyDataProvider">
                <providers>
                  <add name="MydataProvider" type="MyDataProvider" MyAttribute1="MyValue1" MyAttribute2="MyValue2"   />
                </providers>
              </data>
            </configuration>
          

          作为奖励,这里有一个单元测试来验证它是否有效:

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

          【讨论】:

            猜你喜欢
            • 2010-10-20
            • 2011-10-02
            • 2020-08-30
            • 2012-10-04
            • 2015-07-05
            • 2011-05-25
            • 1970-01-01
            • 2012-05-31
            • 1970-01-01
            相关资源
            最近更新 更多