65.9K
CodeProject 正在变化。 阅读更多。
Home

KeyConifg - 一个简单的 .NET 配置库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (9投票s)

2016年7月19日

CPOL

3分钟阅读

viewsIcon

14639

downloadIcon

193

介绍一个小库,可以使您的 .NET 应用程序配置更加容易。

引言

我喜欢尽可能使用强类型定义。 当您抛出字符串并解析值以使配置正确时,使用系统 ConfigurationManager 类来提取配置设置尤其令人烦恼。 很多时候你会发现自己写这样的代码。

const string APPSETTING_PORTNUMBER = "PortNumber"; //this is likely to be elsewhere in the app.

int port = int.Parse(ConfigurationManager.AppSettings[APPSETTING_PORTNUMBER]);

或者您甚至懒得使用常量,并且对直接在代码中硬编码这些应用程序设置键感到内疚。 在我的第一个使用 50 多个这些应用程序设置的应用程序之后,我决定编写一个库,以使整个事情更容易一些。

使用代码

使用 KeyConfig-Net,您可以创建一个类来表示您的应用程序设置配置(或其他配置源)。 KeyConfig-Net 是一个包含大约 200 行代码的库,是一个解决简单问题的简单方案。 让我们抛出一个典型的 .NET web config 配置文件,只有应用程序设置部分。

 <appSettings>
    <add key="HostName" value="localhost"/>
    <add key="PortNumber" value="45345"/>
 </appSettings>

以下代码演示了一个将用于镜像我们配置文件的类。

public class TestConfigClass
{
	[ConfigKey]
	public string HostName { get; set; }

	[ConfigKey]
	public int PortNumber { get; set; }
}

通过将 TestConfigClass 类型指定为类型参数,Key-Config 将使用 TestConfigClass 的默认无参数构造函数来创建 TestConfigClass 的新实例。 然后,它将扫描公共和私有实例属性(非静态)上的 ConfigKey 注释。 这些属性将被赋予来自配置源的值。 这些值也将被解析为正确的类型。 配置源是一个 IConfigSource 实现,它定义了从哪里获取和保存配置值的来源。 Key-Config 目前仅带有 AppSettingsSource 源,但可以扩展。

从 appsettings 提取配置变得像这样简单。

var configSettings = ConfigManager<TestConfigClass>.GetConfig(new AppSettingsSource());

//the following passes
Assert.AreEqual("localhost", configSettings.HostName);
Assert.AreEqual(45345, configSettings.PortNumber);

Key-Config 甚至可以为您保存应用程序设置值。

var source = new AppSettingsSource();
var configSettings = ConfigManager<TestConfigClass>.GetConfig(source);
configSettings.PortNumber = 3423; //changing the port number in appsettings.

ConfigManager<TestConfigClass>.SaveConfig(source, configSettings);

Key-Config 注释还允许您指定一个与属性名称不同的键值,以及指示是否需要配置键。 在下面的代码中,Name 属性将不再分配给 appsettings 中的 Name 配置键,而是将查找 IpAddress

public class TestConfigClass
{
	[ConfigKey(KeyName = "IpAddress", Required = true)]
	public string Name { get; set; }

	[ConfigKey]
	public string Occupation { get; set; }
}

您可以使用以下代码检查是否在获取任何配置设置之前提供了所需的值。 尝试使用缺少必需字段的 GetConfig() 方法访问必需字段将导致抛出异常。

bool areRequiredFulfilled = ConfigManager<TestConfigClass>.CheckRequired(new AppSettingsSource()); //areRequiredFulfilled indicates if all required fields are not null.

幕后

Key-Config 很容易理解底层发生了什么。

该解决方案包括库本身和一个非常小的单元测试项目。 ConfigManager 类包含该项目的主体。 它包含用于操作配置源的静态方法。 配置源通过实现 IConfigSource 接口来定义。 您可以使用此接口轻松扩展 Key-Config,例如使用数据库进行配置设置。 随时向 GitHub 存储库贡献扩展。

 /// <summary>
    /// Conveys a configuration source, of which configuration settings may be derived from.
    /// </summary>
    public interface IConfigSource
    {
        /// <summary>
        /// Indicates whether the source can have configuration settings written to as well as read.
        /// </summary>
        bool CanSet { get; }

        /// <summary>
        /// Indicates whether a specified config key type can be handled as in stored or retrieved as a config value.
        /// </summary>
        /// <param name="objTyp">The type to check.</param>
        /// <returns>True if the type is allowed, false otherwise.</returns>
        bool GetCanHandle(Type objTyp);

        /// <summary>
        /// Sets a value to the configuration source. Is not called ever if the source indicates its read only.
        /// </summary>
        /// <param name="key">The key to the configuration value.</param>
        /// <param name="value">The value that is to be written to the configuration key.</param>
        /// <param name="instanceType">The object type of which configuration values are being mapped to.</param>
        /// <param name="valueType">The value type.</param>
        void SetValue(string key, object value, Type instanceType, Type valueType);

        /// <summary>
        /// Retrieves a value from the configuration source.
        /// </summary>
        /// <param name="key">The key to the configuration value.</param>
        /// <param name="instanceType">The object type of which configuration values are being mapped to.</param>
        /// <param name="valueType">The value type of what is expected to be returned.</param>
        /// <returns>The object retrieved at the specified key, assuming the valueType. Will be null if the value was not found at the specified key.</returns>
        object GetValue(string key, Type instanceType, Type valueType);

    }

ConfigManager 类使用反射从传递的实例类型获取属性值。 反射是 C# 中强大的语言功能,它允许您在运行时检查类型的结构。 在运行时枚举类型的成员的最简单方法是通过访问代码中 Type 对象的成员。

 typeof(TestClass)

访问上面表达式的成员会公开这些潜在的方法。

这些方法在运行时返回类型数据的枚举,您可以检查这些成员并获取它们拥有的属性,甚至可以调用方法并分配字段和属性,所有这些都在您的程序运行时完成。 您可以通过阅读此 MSDN 文章了解有关反射的更多信息: https://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.110).aspx

项目链接

提供指向 GitHub 存储库、NuGet 包和项目文档的链接。

GitHub

https://github.com/jhimes144/KeyConfig

文档

https://www.docify.net/Doc/Project_KeyConfigNet

Nuget

https://nuget.net.cn/packages/KeyConfig-Net/

© . All rights reserved.