功能打散揉碎成模块之后, 最麻烦的莫过于各个模块的配置如何加载.
.NET4.8 之前, 可以用自定义的 JsonConfig (读取 .config 文件太麻烦) 来加载配置,
.NET Core 之后提供了强大的配置系统, 如果在使用那个 JsonConfig
就显的太潦草了.
但是配置分布于各个模块, 模块和模块之间只是通过接口约束, 在这种情况下又如何使用配置呢?
在启动项目里注册 ?
一个两个也就算了, 百八十个的子模块, 按这样搞法, 岂不是一团乱麻?
搞过 IoC
自动注册的, 都知道扫描目录下的 DLL, 然后 AddSingleton
, AddScoped
, AddTransient
, 这个不成功问题.
1 | c#复制代码[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] |
不便之处
麻烦的是, IServiceCollection.Configure<T>(IConfiguration)
方法需要泛型参数 T
。
基于现有知识,要想用上面注册 IoC
的方式来注册配置,那基本是不现实的:
因为 Attribute
目前还没有正式支持泛型
如果不使用泛型 Attribute, 只能想办法变通变通了:
通过反射来实现
扫描 DLL 里实现了
ICfg
接口的类型, 通过Activator
创建一个实例, 然后调用AutoConfigure
1 | c#复制代码public interface ICfg |
这种方法其实还好, 唯一不爽的是, 必须通过 Activator
来创建一个对象, 然后在进行配置注册。
通过泛型特性的实现方法
上面说 Attribute
还未正式支持泛型,意思是说已经可以这样写了:
1 | c#复制代码public class RegistCfgAttribute<T> : RegistCfgAttribute where T : class |
前提是,要启用 preview
语法支持,修改项目文件, 加入 LangVersion
1 | xml复制代码<PropertyGroup> |
如果项目比较多, 一个一个加比较麻烦,也可以通过修改:Directory.Build.props
文件 (放到解决方案根目录下) :
1 | xml复制代码<Project> |
这个方法看起来比较清爽, 但是是 preview
的, 能不能成为正式的, 还不好说。
完整示例
Program.cs
1 | c#复制代码public static IHostBuilder CreateHostBuilder(string[] args) => |
ICfg
配置类 (通过反射来实现):
1 | c#复制代码public interface ICfg |
泛型特性配置类:
1 | c#复制代码public abstract class RegistCfgAttribute : Attribute |
扩展:
1 | c#复制代码public static class RegistExtensions |
本文转载自: 掘金