简体   繁体   English

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

[英]Adding custom attributes to Custom Provider Configuration Section in app.config

I am following this great article on how to create a Provider framework in .NET 我正在关注如何在.NET中创建Provider框架的这篇伟大文章

Basically, this article explains greatly how to end up with a configuration file like the following: 基本上,本文大致解释了如何最终得到如下配置文件:

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

Where the <add/> element allows you to define a provider. 其中<add/>元素允许您定义提供者。

However, I would like to know how to extend the add entry with custom attributes. 但是,我想知道如何使用自定义属性扩展add条目。

For example: 例如:

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

Any help will be greatly appreciated. 任何帮助将不胜感激。

Here is what I finally found. 这是我终于找到的。 This is a very specific question about extending the element with more attributes and how to handle them when implementing a Provider Framework . 这是一个非常具体的问题,关于扩展具有更多属性的元素以及在实现Provider Framework时如何处理它们。 All the answers about custom configuration sections are OK but not addressing the original question. 关于自定义配置部分的所有答案都可以,但不能解决原始问题。

If you need to implement a custom Provider, like the MembershipProvider , but for your own purpose, you need to definitely read this article: Creating Your Own Provider Framework 如果您需要实现自定义提供程序(如MembershipProvider ,但出于您自己的目的,您需要阅读本文: 创建自己的提供程序框架

It is excellent reading. 这是很好的阅读。 Now if you need to extend the element with your own attributes, here is what you need to change... 现在,如果您需要使用自己的属性扩展元素,那么您需要更改...

1) Next is the code discussed in the article (There might be some adaptations): 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) This is the config file that you use for the above code: 2)这是您用于上述代码的配置文件:

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

3) Now, here is what you need to modify in order to use read the attributes in the <add> element in the configuration file. 3)现在,您需要修改以便使用读取配置文件中<add>元素中的属性。

    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) The configuration file looks like this: 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>

And as a bonus, here is a Unit test to validate it works: 作为奖励,这里有一个单元测试来验证它的工作原理:

[TestMethod]
public void RunMyDataProviderTest()
        {
            DataProvider dataProvider = Data.Provider;

            Assert.IsInstanceOfType(dataProvider, typeof(MyDataProvider));

            Assert.AreEqual(dataProvider.MyAttribute1, "MyValue1");
            Assert.AreEqual(dataProvider.MyAttribute2, "MyValue2");
}

Like: 喜欢:

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

?

The c# codes: 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;
        }
    }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM