围绕 Microsoft.Extensions.DependencyInjection.Abstractions
为核心的.Net
模块化开发库.
- 支持异步的模块配置方法;
- 支持基于特性标注的服务自动注入(默认不支持基于继承的服务自动注入);
- 基本和Abp的模块实现方法相同;
- 可拓展的模块加载源,已实现基于
Type
、Assembly
、File
、Directory
的模块加载; IOptions<TOptions>
自动绑定;- 可集成其它模块系统的模块(如Abp),详见示例代码;
- 主项目只依赖
Microsoft.Extensions.DependencyInjection.Abstractions
,Hosting项目额外依赖Hosting.Abstractions
、Configuration.Binder
、Options
; - Mermaid生成工具,方便查看模块依赖关系;
Package | Description |
---|---|
Cuture.Extensions.Modularity | 模块化的核心库 |
Cuture.Extensions.Modularity.Hosting | 对Host的模块化支持库,用于在通用主机中加载模块 |
Install-Package Cuture.Extensions.Modularity
[DependsOn(
typeof(DependsSampleModule1),
typeof(DependsSampleModule2)
)] //定义依赖的模块
[AutoRegisterServicesInAssembly]
public class SampleModule : AppModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//进行模块需要的配置
}
}
[DependsOn]
:声明此模块依赖的模块,加载顺序与声明顺序相同;(可选)[AutoRegisterServicesInAssembly]
:有此特性的模块将会自动将所在程序集中使用ExportServices标记的导出服务注入到DI容器;(可选)1.1.6
之后默认自动注册,使用[DisableAssemblyServicesRegister]
特性进行手动关闭
- 继承
AppModule
:标准的模块只需要继承IAppModule
即可。如果需要单独的配置,则可以单独实现IPreConfigureServices
、IConfigureServices
、IPostConfigureServices
、IOnPreApplicationInitialization
、IOnApplicationInitialization
、IOnPostApplicationInitialization
、IOnApplicationShutdown
以在对应的时机进行配置,或直接继承AppModule
并重写对应的方法;所有方法都有异步版本IPreConfigureServicesAsync
、IConfigureServicesAsync
、IPostConfigureServicesAsync
、IOnPreApplicationInitializationAsync
、IOnApplicationInitializationAsync
、IOnPostApplicationInitializationAsync
、IOnApplicationShutdownAsync
,或直接继承AsyncAppModule
;
var services = new ServiceCollection();
//加载模块
services.LoadModule<SampleModule>() //直接从类型加载
.LoadModuleFile(modulePath) //从文件加载
.LoadModuleDirectory(source =>
{
source.SearchDepth = 5; //设置文件夹搜索深度
}, moduleDirectory) //从文件夹加载
.ModuleLoadComplete() //必须调用此方法,以确认模块加载完成
using (var serviceProvider = services.BuildServiceProvider())
{
//必须调用此方法,以初始化模块
serviceProvider.InitializationModulesWithOutHostLifetime();
//这里使用初始化了模块的serviceProvider
//关闭模块
serviceProvider.ShutdownModules();
}
Note:
- 直接使用DI容器时,不会在控制台等关闭时,自动调用模块结束方法(使用Host时会),需要手动调用;
Install-Package Cuture.Extensions.Modularity.Hosting
Host.CreateDefaultBuilder(args)
.LoadModule<SampleModule>() //直接从类型加载
.LoadModuleFile(modulePath) //从文件加载
.LoadModuleDirectory(source =>
{
source.SearchDepth = 5; //设置文件夹搜索深度
}, moduleDirectory) //从文件夹加载
.UseConsoleLifetime()
.InitializationModules() //必须调用此方法,以初始化模块
.Run();
- 也可以通过配置主机DI容器的方法来使用
更多细节详见示例代码;
- 需要为类型
所在程序集
的模块
标记特性[AutoRegisterServicesInAssembly]
[ExportServices(ServiceLifetime.Singleton, AddDIMode.Replace, typeof(IHello))]
public class Hello : IHello
{
public string SayHello()
{
return "Hello";
}
}
示例代码会自动将Hello
类型以单例
模式注册为IHello
服务,并在注入时使用Replace
方法。
参数:
- ServiceLifetime:注册的生命周期类型;
- AddDIMode:注册的方法,包括
Add
、TryAdd
、Replace
;
除示例的ExportServices
外,还有ExportSingletonServices
、ExportScopedServices
、ExportTransientServices
等多个拓展特性的重载实现;
- 自动查找模块中继承了
IOptions<TOptions>
的类; - 使用其完整名称为路径,在
IConfiguration
查找节点,并绑定值; - 如
A
类命名空间为B.C.D.E.F
,则IConfiguration
查找路径为B:C:D:E:F:A
; - Note: 构建过程中必须有可访问的
IConfiguration
!!! 详见示例项目;
示例配置代码:
- 在构建中调用
AutoBindModuleOptions()
方法即可;
Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(builder => builder.AddJsonFile("appsettings.Development.json"))
.LoadModule<HostSampleModule>()
.AutoBindModuleOptions() //自动使用 IConfiguration 绑定模块中继承了 IOptions<TOptions> 的类
.UseConsoleLifetime()
.InitializationModules()
.Run();
参考示例项目OtherModuleSystemAdaptSample
var abpModuleDescriptors = AppModuleDependencyUtil.FindAllDependedModuleDescriptors(typeof(XXXModule));
var mermaidString = abpModuleDescriptors.ToMermaidString();
然后将mermaidString
复制到支持mermaid
的编辑器就能查看模块依赖关系了。