位置: 文档库 > C#(.NET) > C#自定读取配置文件类

C#自定读取配置文件类

AlleyDragon 上传于 2020-02-20 11:43

《C#自定义读取配置文件类》

在.NET开发中,配置文件是存储应用程序参数的核心方式。从传统的.config文件到现代的JSON/YAML配置,开发者需要灵活处理不同格式的配置数据。本文将深入探讨如何设计一个可扩展的自定义配置文件读取类,覆盖配置解析、类型转换、错误处理等关键环节,帮助开发者构建健壮的配置管理方案。

一、配置文件处理的核心挑战

传统配置文件处理存在三大痛点:

1. 格式依赖性强:System.Configuration命名空间仅支持XML格式,无法直接处理JSON/YAML

2. 类型转换繁琐:需要手动处理字符串到复杂类型的转换

3. 扩展性差:难以适应自定义配置结构或动态配置更新

以App.config为例,获取连接字符串的常规方式:

var connectionString = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
// 存在空引用风险且仅支持特定节点类型

二、自定义配置读取类设计原则

优秀配置类应具备以下特性:

  • 格式无关性:支持XML/JSON/YAML等多种格式

  • 强类型支持:自动完成类型转换

  • 默认值机制:提供安全的回退方案

  • 配置热更新:支持运行时配置刷新

  • 依赖注入友好:便于在ASP.NET Core等框架中使用

三、基础实现:抽象配置读取器

首先定义配置读取器的抽象基类:

public abstract class ConfigReaderBase
{
    protected string _filePath;
    protected DateTime _lastModified;

    public ConfigReaderBase(string filePath)
    {
        _filePath = filePath ?? throw new ArgumentNullException(nameof(filePath));
        Refresh();
    }

    public abstract T GetValue(string key, T defaultValue = default);
    
    public virtual void Refresh()
    {
        _lastModified = File.GetLastWriteTime(_filePath);
        // 子类实现具体刷新逻辑
    }

    protected abstract IDictionary ParseConfig();
}

四、JSON配置读取器实现

基于Newtonsoft.Json的实现示例:

public class JsonConfigReader : ConfigReaderBase
{
    private IDictionary _configCache;

    public JsonConfigReader(string filePath) : base(filePath) { }

    public override T GetValue(string key, T defaultValue = default)
    {
        RefreshIfNeeded();
        
        if (_configCache.TryGetValue(key, out var value) && value != null)
        {
            try { return (T)Convert.ChangeType(value, typeof(T)); }
            catch { return defaultValue; }
        }
        return defaultValue;
    }

    private void RefreshIfNeeded()
    {
        var currentModified = File.GetLastWriteTime(_filePath);
        if (currentModified > _lastModified) Refresh();
    }

    protected override IDictionary ParseConfig()
    {
        var json = File.ReadAllText(_filePath);
        var jobject = JObject.Parse(json);
        
        _configCache = jobject.Properties()
            .ToDictionary(p => p.Name, p => (object)p.Value.ToObject());
        
        return _configCache;
    }
}

五、XML配置读取器实现

处理传统.config文件的实现:

public class XmlConfigReader : ConfigReaderBase
{
    public XmlConfigReader(string filePath) : base(filePath) { }

    public override T GetValue(string key, T defaultValue = default)
    {
        var doc = new XmlDocument();
        doc.Load(_filePath);
        
        var node = doc.SelectSingleNode($"//add[@key='{key}']");
        if (node?.Attributes["value"] != null)
        {
            try 
            {
                var valueStr = node.Attributes["value"].Value;
                return (T)TypeDescriptor.GetConverter(typeof(T))
                    .ConvertFromInvariantString(valueStr);
            }
            catch { return defaultValue; }
        }
        return defaultValue;
    }

    protected override IDictionary ParseConfig()
    {
        // 实现类似JSON的缓存机制
        throw new NotImplementedException();
    }
}

六、高级功能实现

1. 配置节分区处理:

public class SectionalConfigReader : ConfigReaderBase
{
    private Dictionary> _sections;

    public T GetSectionValue(string section, string key, T defaultValue = default)
    {
        if (_sections.TryGetValue(section, out var sectionData) && 
            sectionData.TryGetValue(key, out var value))
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        return defaultValue;
    }

    // 实现ParseConfig时解析分区结构
}

2. 配置变更监听:

public class WatchingConfigReader : ConfigReaderBase
{
    private FileSystemWatcher _watcher;

    public WatchingConfigReader(string filePath) : base(filePath)
    {
        _watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath))
        {
            Filter = Path.GetFileName(filePath),
            EnableRaisingEvents = true
        };
        _watcher.Changed += (s, e) => Refresh();
    }

    // 其他方法实现...
}

七、ASP.NET Core集成方案

1. 创建IConfigReader接口:

public interface IConfigReader
{
    T GetValue(string key, T defaultValue = default);
    void Refresh();
}

2. 实现服务注册扩展:

public static class ConfigReaderExtensions
{
    public static IServiceCollection AddCustomConfig(this IServiceCollection services, 
        string filePath, ConfigFormat format = ConfigFormat.Json)
    {
        switch (format)
        {
            case ConfigFormat.Json:
                services.AddSingleton(new JsonConfigReader(filePath));
                break;
            case ConfigFormat.Xml:
                services.AddSingleton(new XmlConfigReader(filePath));
                break;
        }
        return services;
    }
}

3. 在Startup.cs中使用:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCustomConfig("appsettings.json", ConfigFormat.Json);
    // 其他服务注册...
}

八、性能优化策略

1. 配置缓存机制:

public class CachedConfigReader : ConfigReaderBase
{
    private readonly object _lock = new object();
    private IDictionary _cache;
    private DateTime _cacheTime;
    private readonly TimeSpan _cacheDuration = TimeSpan.FromSeconds(30);

    protected override IDictionary ParseConfig()
    {
        lock (_lock)
        {
            if (_cache != null && DateTime.Now - _cacheTime 

2. 异步加载支持:

public class AsyncConfigReader : ConfigReaderBase
{
    private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

    public override async Task GetValueAsync(string key, T defaultValue = default)
    {
        await _semaphore.WaitAsync();
        try
        {
            var config = await Task.Run(() => ParseConfig());
            if (config.TryGetValue(key, out var value))
                return (T)Convert.ChangeType(value, typeof(T));
            return defaultValue;
        }
        finally { _semaphore.Release(); }
    }
}

九、错误处理最佳实践

1. 配置异常封装:

public class ConfigException : Exception
{
    public ConfigExceptionType ExceptionType { get; }
    
    public ConfigException(string message, ConfigExceptionType type) 
        : base(message) => ExceptionType = type;
}

public enum ConfigExceptionType
{
    FileNotFound,
    ParseError,
    TypeConversionFailed,
    KeyNotFound
}

2. 安全访问方法:

public static class ConfigReaderExtensions
{
    public static T SafeGetValue(this IConfigReader reader, string key, 
        T defaultValue = default, Action errorHandler = null)
    {
        try { return reader.GetValue(key, defaultValue); }
        catch (Exception ex)
        {
            errorHandler?.Invoke(ex);
            return defaultValue;
        }
    }
}

十、完整示例:企业级配置管理器

public class EnterpriseConfigManager : IConfigReader, IDisposable
{
    private readonly IConfigReader _primaryReader;
    private readonly IConfigReader _fallbackReader;
    private readonly ILogger _logger;
    private bool _disposed;

    public EnterpriseConfigManager(
        IConfigReader primary, 
        IConfigReader fallback,
        ILogger logger)
    {
        _primaryReader = primary ?? throw new ArgumentNullException(nameof(primary));
        _fallbackReader = fallback;
        _logger = logger;
    }

    public T GetValue(string key, T defaultValue = default)
    {
        try
        {
            var value = _primaryReader.GetValue(key);
            return Equals(value, default(T)) && _fallbackReader != null 
                ? _fallbackReader.GetValue(key, defaultValue) 
                : value;
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, $"Config access failed for key: {key}");
            return _fallbackReader?.GetValue(key, defaultValue) ?? defaultValue;
        }
    }

    public void Refresh()
    {
        _primaryReader.Refresh();
        _fallbackReader?.Refresh();
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            (_primaryReader as IDisposable)?.Dispose();
            (_fallbackReader as IDisposable)?.Dispose();
            _disposed = true;
        }
    }
}

关键词:C#配置管理、自定义配置读取器、JSON配置、XML配置、配置缓存、异步加载、依赖注入、ASP.NET Core集成、配置热更新

简介:本文详细介绍了C#中自定义配置文件读取类的设计实现,涵盖JSON/XML等格式处理、配置缓存异步加载、错误处理等核心功能,提供了企业级配置管理器的完整实现方案,适用于.NET Framework和.NET Core环境。

《C#自定读取配置文件类.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档