ShutdownModules()
方法,实现对各个模块资源的释放;
public async Task ShutdownModules(){foreach (var module in _moduleContainer.Modules){await module.Instance.Shutdown(new ApplicationContext(_serviceProvider, _moduleContainer));}}
模块的类型在Silky框架中,我将模块的类型划分为如下几种类型:
- 模块的定义
SilkyModule
: SilkyModule是一个抽象的模块,用于定义模块的概念;其他业务模块必须要派生自该类;
- 业务模块: 直接派生自
SilkyModule
类的非抽象类,Silky框架中,几乎所有的包在通过定义业务模块后从而实现模块化编程的,很多核心的包都是业务模块,如:SilkyModule
、ConsulModule
、DotNettyModule
等等模块都属于业务模块;
- Http类型的业务模块:该类型的业务模块派生自HttpSilkyModule,相比一般的业务模块,该类型的模块增加了
Configure(IApplicationBuilder application)
方法,该类型的模块一般用于通过web主机构建的微服务应用或是网关中,可以在Configure()
方法中通过IApplicationBuilder
引用http中间件,在silky框架中,诸如:CorsModule
、IdentityModule
、MiniProfilerModule
等均是该类型的模块; 需要特别注意的是,需要http业务模块配置的中间件起效果的话 , 不要忘记需要在Startup
类中的Configure
进行如下配置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.ConfigureSilkyRequestPipeline();}
- 启动模块:该类型的模块派生自StartUpModule的非抽象类;在模块加载过程中,通过指定启动模块,从而得知模块的依赖关系,模块加载器会通过模块的依赖对模块进行排序,从而影响应用在启动时各个模块的执行的先后顺序;Silky模块预定义了多个启动模块,可以用于不同silky主机的构成:A)
DefaultGeneralHostModule
用于构建普通的业务主机,一般用于托管只提供RPC服务的微服务应用;B)WebSocketHostModule
用于构建提供WebSocket服务能力的业务主机;C)DefaultWebHostModule
用于构建能够提供Http服务的业务主机,对外可以提供http服务,也可以用于内部rpc通信;D)DefaultGatewayHostModule
用于构建网关微服务,一般为微服务集群暴露对外部的http访问端口,通过路由机制,将http请求转发到具体某个服务条目,对内通过RPC进行通信;
模块的加载Silky所有的模块是在什么时候以及如何进行加载和排序的呢?
在之前的构建服务引擎的一章中,我们知道在
AddSilkyServices<T>()
方法中,我们通过泛型T
来指定应用程序的启用模块StartUpModule
类型 。并构建了模块加载器对象ModuleLoader
,并且将模块加载器对象作为服务引擎的LoadModules()
方法参数:public static IEngine AddSilkyServices<T>(this IServiceCollection services, IConfiguration configuration,IHostEnvironment hostEnvironment) where T : StartUpModule{var moduleLoader = new ModuleLoader();engine.LoadModules<T>(services, moduleLoader);}
在服务引擎SilkyEngine
实现类中,除了实现IEngine
接口之外,还需要实现了IModuleContainer
接口,IModuleContainer
只定义了一个只读属性Modules
,要求通过该属性获取所有的模块;在服务引擎中,我们通过模块加载器对象moduleLoader.LoadModules()
方法实现对模块的加载与解析,并对属性Modules
进行赋值;internal sealed class SilkyEngine : IEngine, IModuleContainer{// 其他代码略...public void LoadModules<T>(IServiceCollection services, IModuleLoader moduleLoader)where T : StartUpModule{Modules = moduleLoader.LoadModules(services, typeof(T));}// 实现IModuleContainer定义的属性public IReadOnlyList<ISilkyModuleDescriptor> Modules { get; private set; }}
模块加载器ModuleLoader要求传递两个参数,一个是IServiceCollection
的对象services
, 一个是启动模块StartupModule
的的类型typeof(T)
;下面我们来描述模块加载的过程:- 通过
SilkyModuleHelper.FindAllModuleTypes(startupModuleType)
查找到启动模块StartupModule
类型依赖的所有模块类型;
- 通过反射创建模块的实例,并通过
IServiceCollection
注册单例的模块实例,并创建模块描述符SilkyModuleDescriptor
;
- 根据模块的依赖关系对模块进行排序;
推荐阅读
- 一篇文章带你了解轻量级Web服务器——Nginx简单入门
- iphone12有无线充电吗_iphone12可以使用无线充电吗
- 如何转账到支付宝(支付宝不绑卡怎么把钱转到微信)
- Seata 环境搭建
- 四十七 SpringCloud微服务实战——搭建企业级开发框架:【移动开发】整合uni-app搭建移动端快速开发框架-添加Axios并实现登录功能
- 记录一次sshd服务启动失败
- 微信小程序仿手机相册组件——简单版
- 3 Python全栈工程师之从网页搭建入门到Flask全栈项目实战 - 入门Flask微框架
- 【Serverless】云函数微信小程序
- ipad如何分屏工作(ipad微信分屏怎么取消)