将自定义属性添加到 app.config 中的自定义提供程序配置部分

发布于 2025-01-03 16:25:56 字数 1024 浏览 1 评论 0原文

我正在关注这篇关于 如何在 .NET 中创建 Provider 框架

基本上,本文详细解释了如何最终得到如下所示的配置文件

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

元素允许您定义提供者。

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

例如:

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

任何帮助将不胜感激。

I am following this great article on how to create a Provider framework in .NET

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.

However, I would like to know how to extend the add entry with custom attributes.

For example:

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

Any help will be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

香草可樂 2025-01-10 16:25:56

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

如果您需要实现自定义 Provider,例如 MembershipProvider,但为了您自己的目的,您一定需要阅读这篇文章:创建您自己的框架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) 现在,您需要修改以下内容才能使用读取配置文件中 元素中的属性。

    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");
}

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. 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

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):

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:

  <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.

    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:

  <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");
}
秋意浓 2025-01-10 16:25:56

喜欢:

<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;
        }
    }
}

Like:

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

?

The c# codes:

/// <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;
        }
    }
}
风苍溪 2025-01-10 16:25:56

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

You need to create a custom ConfigurationSection implementation, which will allow you to create a customized config tree like you provided.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文