Biwen.Settings如何添加对IConfiguration&IOptions的集成支持
Biwen.Settings 是一个简易的配置项管理模块,主要的作用就是可以校验并持久化配置项,比如将自己的配置存储到数据库中,JSON文件中等
使用上也是很简单,只需要在服务中注入配置,
比如我们有一个GithubSetting的配置项,我们只需要定义好对象然后注入到Service中即可:
[Description("Github配置")] public class GithubSetting : ValidationSettingBase{ [Description("Github用户名")] public string? UserName { get; set; } = "vipwan"; [Description("Github仓库")] public string? Repository { get; set; } = "Biwen.Settings"; [Description("Github Token")] public string? Token { get; set; } = ""; public GithubSetting() { //验证规则 RuleFor(x => x.UserName).NotEmpty().Length(3, 128); RuleFor(x => x.Repository).NotNull().NotEmpty().Length(3, 128); RuleFor(x => x.Token).NotNull().NotEmpty().Length(3, 128); } }
@inject GithubSetting GithubSetting;//直接对象注入
尽管这样已经足够好用且便捷,但是对于习惯了使用IConfiguration
和IOptions
的朋友来说还是有些不习惯,其实实现对IConfiguration的支持还是很简单的,实现一下IConfigurationProvider
即可,我们来动手实现一个名为BiwenSettingConfigurationProvider
的Provider:
internal class Events { ////// Channel队列 /// public static readonly Channel<(bool IsChanged, string? SettingName)> ConfigrationChangedChannel = Channel.CreateUnbounded<(bool IsChanged, string? SettingName)>(); } internal sealed class BiwenSettingConfigurationSource(bool autoRefresh = true) : IConfigurationSource { public IConfigurationProvider Build(IConfigurationBuilder builder) => new BiwenSettingConfigurationProvider(autoRefresh); } internal class BiwenSettingConfigurationProvider : ConfigurationProvider, IDisposable, IAsyncDisposable { public BiwenSettingConfigurationProvider(bool autoRefresh) { if (Settings.ServiceRegistration.ServiceProvider is null) { throw new BiwenException("必须首先注册Biwen.Setting模块,请调用:services.AddBiwenSettings()"); } if (autoRefresh) { StartAlertAsync(cts.Token); } } private CancellationTokenSource cts = new(); ////// 使用Channel通知配置变更,如果有事件更新则重新加载 /// /// ///public Task StartAlertAsync(CancellationToken cancellationToken) { _ = Task.Run(async () => { while (!cancellationToken.IsCancellationRequested) { _ = await Events.ConfigrationChangedChannel.Reader.ReadAsync(cancellationToken); Load(); //通知配置变更 OnReload(); } }, cancellationToken); return Task.CompletedTask; } //从SettingManager中加载配置项 public override void Load() { Dictionary dics = []; using var scope = Settings.ServiceRegistration.ServiceProvider.CreateScope(); var settingManager = scope.ServiceProvider.GetRequiredService (); var settings = settingManager.GetAllSettings()!; foreach (var setting in settings) { if (setting.SettingContent is null) continue; if (JsonNode.Parse(setting.SettingContent) is not JsonObject json) continue; foreach (var item in json) { dics.TryAdd($"{setting.SettingName}:{item.Key}", item.Value?.ToString()); } } Data = dics; } public void Dispose() { cts.Cancel(); Events.ConfigrationChangedChannel.Writer.Complete(); } public ValueTask DisposeAsync() { cts.Cancel(); Events.ConfigrationChangedChannel.Writer.Complete(); return ValueTask.CompletedTask; } }
内部通过Channel实现变更通知,
internal class ConfigurationMediratorDoneHandler(ILoggerlogger) : IMediratorDoneHandler { public Task OnPublishedAsync (T @event) where T : ISetting, new() { Events.ConfigrationChangedChannel.Writer.TryWrite((true, typeof(T).Name)); logger.LogInformation($"Setting Changed: {typeof(T).Name},并通知Configuration刷新!"); return Task.CompletedTask; } }
然后老规矩我们扩展一下IServiceCollection
:
public static class ServiceRegistration { internal static IServiceCollection AddBiwenSettingConfiguration(this IServiceCollection services) { //ConfigurationMediratorDoneHandler services.AddSingleton(); return services; } /// /// 提供对IConfiguration,IOptions的支持 /// /// /// ///public static ConfigurationManager AddBiwenSettingConfiguration( this ConfigurationManager manager, IServiceCollection serviceDescriptors, bool autoRefresh = true) { var sp = Settings.ServiceRegistration.ServiceProvider ?? throw new BiwenException("必须首先注册Biwen.Setting模块,请调用:services.AddBiwenSettings()"); //添加订阅 if (autoRefresh) { serviceDescriptors.AddBiwenSettingConfiguration(); } IConfigurationBuilder configBuilder = manager; configBuilder.Add(new BiwenSettingConfigurationSource(autoRefresh)); var settings = ASS.InAllRequiredAssemblies.ThatInherit(typeof(ISetting)).Where(x => x.IsClass && !x.IsAbstract).ToList(); //注册ISetting settings.ForEach(x => { //IOptions DI manager?.GetSection(x.Name).Bind(GetSetting(x, sp)); }); return manager; } static object GetSetting(Type x, IServiceProvider sp) { var settingManager = sp.GetRequiredService (); var cache = sp.GetRequiredService (); //使用缓存避免重复反射 var md = cache.GetOrCreate($"GenericMethod_{x.FullName}", entry => { MethodInfo methodLoad = settingManager.GetType().GetMethod(nameof(settingManager.Get))!; MethodInfo generic = methodLoad.MakeGenericMethod(x); return generic; }); return md!.Invoke(settingManager, null)!; } }
最后在启动时调用AddBiwenSettingConfiguration扩展即可
builder.Configuration.AddBiwenSettingConfiguration(builder.Services, true);
最后按下面的形式注册就可以了:
@inject GithubSetting GithubSetting;//直接对象注入 @inject IOptionsIOP; //通过IOptions注入 @inject IConfiguration Configuration;//IConfiguration ...
源代码我发布到了GitHub,欢迎star!
https://github.com/vipwan/Biwen.Settings
https://github.com/vipwan/Biwen.Settings/tree/master/Biwen.Settings/Extensions/Configuration
到此这篇关于Biwen.Settings添加对IConfiguration&IOptions的集成支持的文章就介绍到这了,更多相关Biwen.Settings IConfiguration&IOptions集成内容请搜索科站长以前的文章或继续浏览下面的相关文章希望大家以后多多支持科站长!
上一篇:Asp Net Core开发笔记之如何给SwaggerUI加上登录保护功能
栏 目:ASP.NET
下一篇:.NET集成DeveloperSharp实现高效分页与无主键分页
本文标题:Biwen.Settings如何添加对IConfiguration&IOptions的集成支持
本文地址:https://www.fushidao.cc/wangluobiancheng/3241.html
您可能感兴趣的文章
- 03-31详解如何在.NET代码中使用本地部署的Deepseek语言模型
- 02-06.net core如何使用Nacos注册中心
- 01-28使用.NET8构建一个高效的时间日期帮助类
- 01-26.NET Core GC压缩(compact_phase)底层原理解析
- 01-24在ASP.NET中读写TXT文本文件的多种方法
- 01-24在ASP.NET中读写XML数据的多种方法
- 01-24.NET轻松实现Excel转PDF的三种方法详解
- 01-23.NET9 AOT部署方案详解
- 01-23.NET NativeAOT 用法指南
- 01-23iis部署前后端分离项目全过程(Vuet前端和.NET6后端)


阅读排行
推荐教程
- 03-31详解如何在.NET代码中使用本地部署的Deepseek语言模型
- 11-23移动互联网广告有哪些模式?
- 11-22.net 应对网站访问压力的方案总结
- 11-22详解ASP.NET提取多层嵌套json数据的方法
- 11-23网站投放广告如何达到最好的效果
- 11-22.net 应对网站访问压力的方案总结
- 11-23网站打开速度慢解决办法
- 11-23草根站长为什么喜欢做门户站
- 11-22ASP.NET MVC分页问题解决
- 11-22ASP.NET编程简单实现生成静态页面的方法