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

2024-01-17

我正在关注这篇精彩的文章 in .NET

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

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

哪里的<add/>元素允许您定义提供者。

不过我想知道如何延长add具有自定义属性的条目。

例如:

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

任何帮助将不胜感激。


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

如果您需要实现自定义提供程序,例如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);

        /// <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)现在,您需要修改以下内容才能使用读取中的属性<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)配置文件如下所示:

  <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");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 为什么基类必须有一个带有 0 个参数的构造函数?

    这不会编译 namespace Constructor0Args class Base public Base int x class Derived Base class Program static void Main string a
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 如何在 GCC 5 中处理双 ABI?

    我尝试了解如何克服 GCC 5 中引入的双重 ABI 的问题 但是 我没能做到 这是一个重现错误的非常简单的示例 我使用的GCC版本是5 2 如您所见 我的主要函数 在 main cpp 文件中 非常简单 main cpp include
  • WPF/数据集:如何通过 XAML 将相关表中的数据绑定到数据网格列中?

    我正在使用 WPF DataSet 连接到 SQL Server Express XAML 和 C Visual Studio 2013 Express 我从名为 BankNoteBook 的现有 SQL Server Express 数据
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐