Biwen.Settings 是一个简易的配置项管理模块,主要的作用就是可以校验并持久化配置项,比如将自己的配置存储到数据库中,JSON文件中等

使用上也是很简单,只需要在服务中注入配置即可,

比如我们有一个GithubSetting的配置项,我们只需要定义好对象然后注入到Service中即可:

    [Description("Github配置")]
public class GithubSetting : ValidationSettingBase<GithubSetting>
{
[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; } = "";
/// <summary>
/// 短名称
/// </summary>
public override string? SettingName => this.GetType().Name;
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;//直接对象注入

尽管这样已经足够好用且便捷,但是对于习惯了使用IConfigurationIOptions的朋友来说还是有些不习惯,其实实现对IConfiguration的支持还是很简单的,实现一下IConfigurationProvider即可,我们来动手实现一个名为BiwenSettingConfigurationProvider的Provider:

    internal class Events
{
/// <summary>
/// Channel队列
/// </summary>
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(); /// <summary>
/// 使用Channel通知配置变更,如果有事件更新则重新加载
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
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<string, string?> dics = []; using var scope = Settings.ServiceRegistration.ServiceProvider.CreateScope();
var settingManager = scope.ServiceProvider.GetRequiredService<ISettingManager>();
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(ILogger<ConfigurationMediratorDoneHandler> logger) : IMediratorDoneHandler
{
public Task OnPublishedAsync<T>(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<IMediratorDoneHandler, ConfigurationMediratorDoneHandler>();
return services;
} /// <summary>
/// 提供对IConfiguration,IOptions的支持
/// </summary>
/// <param name="manager"></param>
/// <param name="autoRefresh"></param>
/// <returns></returns>
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<ISettingManager>();
var cache = sp.GetRequiredService<IMemoryCache>(); //使用缓存避免重复反射
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 IOptions<GithubSetting> IOP; //通过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的集成支持的更多相关文章

  1. Webstorm添加新建.vue文件功能并支持高亮vue语法和es6语法

    转载:https://blog.csdn.net/qq_33008701/article/details/56486893 Webstorm 添加新建.vue文件功能并支持高亮vue语法和es6语法 ...

  2. 一般源码安装添加的GD库 是不支持 jpeg 格式的图片的

    一般源码安装添加的GD库 是不支持 jpeg 格式的图片的,只支持如下格式 GD Support enabled GD Version bundled (2.0.34 compatible) GIF ...

  3. 为 WPF 程序添加 Windows 跳转列表的支持

    原文:为 WPF 程序添加 Windows 跳转列表的支持 Windows 跳转列表是自 Windows 7 时代就带来的功能,这一功能是跟随 Windows 7 的任务栏而发布的.当时应用程序要想用 ...

  4. sublime使用技巧之添加到右键菜单、集成VI

    熟悉开发工具,减少多余的操作流程有助于提高开发效率,而Sublime Text 2是sublime产品的经典版本,因此本文基于Sublime Text 2讲解sublime的使用技巧. VI的主要作用 ...

  5. 为Github仓库添加Github Actions实现持续集成: Android apk自动编译发布以及github pages同步推送coding.net

    内容转载自我的博客 目录 说明 1. 编写Android项目的CI配置文件 2. 编写Jekyll项目的CI配置文件 2.1 配置coding.net 2.2 配置github 2.3 自动部署到co ...

  6. [OIDC in Action] 3. 基于OIDC(OpenID Connect)的SSO(添加Github OAuth 2.0的支持)

    在上上一篇基于OIDC的SSO的登录页面的截图中有出现QQ登录的地方.这个其实是通过扩展OIDC的OpenID Provider来实现的,OpenID Provider简称OP,OP是OIDC的一个很 ...

  7. 自己动手为Spark 2.x添加ALTER TABLE ADD COLUMNS语法支持

    SparkSQL从2.0开始已经不再支持ALTER TABLE table_name ADD COLUMNS (col_name data_type [COMMENT col_comment], .. ...

  8. Webstorm 添加新建.vue文件功能并支持高亮vue语法和es6语法

    添加新建.vue文件功能 ①Webstorm 右上角File-Plugins 搜索vue如果没有就去下载 点击serch in repositories ②点击安装vue.js ③安装成功后点击右下角 ...

  9. springboot添加对listener,servlet,filter的支持

    比较常用的方式就是使用注解来添加对 监听器,过滤器,servlet的支持. 1.首先在启动类上添加  @ServletComponentScan  开启 对监听器,过滤器,servlet的注解扫描. ...

  10. 如果给IIS添加防火墙入站配置,支持外部或者局域网访问

    背景简介 也许你试着在本机IIS运行了一些网站,但是奇怪的是,同网络的终端却无法访问你,这时候极有可能被防火墙拦截了,所以我们要找到正确的姿势来开启魔法了. 找到入站规则设置 不管你是Win7还是Wi ...

随机推荐

  1. C#使用PaddleOCR进行图片文字识别✨

    PaddlePaddle介绍 PaddlePaddle(飞桨)是百度开发的深度学习平台,旨在为开发者提供全面.灵活的工具集,用于构建.训练和部署各种深度学习模型.它具有开放源代码.高度灵活性.可扩展性 ...

  2. HarmonyOS实现几种常见图片点击效果

    一. 样例介绍 HarmonyOS提供了常用的图片.图片帧动画播放器组件,开发者可以根据实际场景和开发需求,实现不同的界面交互效果,包括:点击阴影效果.点击切换状态.点击动画效果.点击切换动效. 相关 ...

  3. 全局模型可解释之部分依赖图:Partial Dependence Plot

    本部分是来自大纲 模型可解释的一个子分支. 部分依赖图可以表示1个或者2个特征对模型的预测结果所能产生的边际效应.同时也能展示1个特征和label直接是否具有:线性相关性.单调性等. 当我们把pdp应 ...

  4. Graph Embedding-DeepWalk

    一言以蔽之,DeepWalk是在graph上,通过随机游走来产生一段定长的结点序列,并将其通过word2vec的方式获得各个结点的embedding的算法. DeepWalk一共涉及以下几个内容: 随 ...

  5. Code Aesthetic

    01 Abstraction Abstraction is the process of aggregating code with high similarity among multiple cl ...

  6. Spring Cloud Config:外部集中化配置管理

    Spring Cloud Config:外部集中化配置管理 SpringCloud学习教程 SpringCloud Spring Cloud Config 可以为微服务架构中的应用提供集中化的外部配置 ...

  7. mysql 必知必会整理—sql 简单语句[二]

    前言 简单整理一下sql 排序与过滤. 正文 在这里需要创建一下一个数据库实例. 为了方便直接用docker 创建一下啊,方便简洁. https://hub.docker.com/_/mysql 按照 ...

  8. 关于<property name="hibernate.hbm2ddl.auto"></property>中的参数填写

    hibernate的数据库表自动生成参数 关于<property name="hibernate.hbm2ddl.auto"></property>中的参数 ...

  9. N个技巧,编写更高效 Dockerfile|云效工程师指北

    简介:云原生时代下软件的构建和部署离不开容器技术.提到容器,几乎大家下意识都会联想到 Docker .而 Docker 中有两个非常重要的概念,一个是Image(镜像),一个是Container(容器 ...

  10. Quick BI产品核心功能大图(六)开放集成

    ​简介:企业想要拥有领先的数据分析能力,自研往往需要投入巨大的人力和财力. Quick BI作为唯一一个连续两年入选Gartner魔力象限的中国BI产品,具备强大的全链路开放集成能力,可以轻松的与企业 ...