执行所有模块的初始化方法
为什么要执行模块初始化
每个模块可能有自己的依赖服务(比如仓储、服务类、配置等),初始化时统一注册到依赖注入(DI)容器。
之前我们创建ReflectionHelper方法进行程序集的获取。
获取之后得让他们准备好运行起来。
好处:传统写法把所有服务注册写在 Program.cs,随着模块增多代码会非常混乱。而用初始化器,每个模块只管自己,清晰明了,职责单一。
找到所有实现初始化接口的类
1 | public interface IModuleInitializer |
该接口的核心目的是为每个独立模块提供一个注册依赖注入服务的统一入口点。
1 | public class MyModuleA : IModuleInitializer |
接口的模块初始化器
1 | public static class ModuleInitializerExtensions |
1 | public static IServiceCollection RunModuleInitializers(this IServiceCollection services, IEnumerable<Assembly> assemblies) |
是一个扩展方法:挂在IServiceCollection上,可以链式调用
。
接收一组程序集参数assembies,用于模块扫描。
什么是链式调用:链式调用(Fluent Interface 或叫 Method Chaining)是一种编程风格,其特点是连续调用多个方法,每个方法调用之后都返回当前对象或其他对象,以便继续调用下一个方法。
示例:
1 | builder.Services |
1 | foreach (var asm in assemblies) |
遍历每个程序集,取出所有类型。
1 | var moduleInitializerTypes = types.Where(t => !t.IsAbstract && typeof(IModuleInitializer).IsAssignableFrom(t)); |
找出所有非抽象类,实现了IModuleInitializer接口类型(包括继承的)
1 | foreach (var implType in moduleInitializerTypes) |
利用反射创建模块初始化实例。
如果创建失败(返回ull),抛出异常。
1 | initializer.Initialize(services); |
调用模块初始化逻辑,让模块把自己的服务注入进来。
1 | return services; |
返回自身,便于链式调用。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 YOUXIANYU!
评论