Silky微服务框架之模块

模块的定义Silky是一个包括多个nuget包构成的模块化的框架,每个模块将程序划分为一个个小的结构,在这个结构中有着自己的逻辑代码和自己的作用域,不会影响到其他的结构 。
模块类一般地,一个模块的定义是通过在该程序集内创建一个派生自 SilkyModule的类,如下所示:
public class RpcModule : SilkyModule{}SilkyModule是一个抽象的类,它定义了模块的基础方法,体现了模块在框架中的作用;
SilkyModule模块定义的核心代码如下所示:
public abstract class SilkyModule : Autofac.Module, ISilkyModule, IDisposable{protected SilkyModule(){Name = GetType().Name.RemovePostFix(StringComparison.OrdinalIgnoreCase, "Module");}protected override void Load([NotNull] ContainerBuilder builder){base.Load(builder);RegisterServices(builder);}public virtual void ConfigureServices(IServiceCollection services, IConfiguration configuration){}protected virtual void RegisterServices([NotNull] ContainerBuilder builder){}public virtual Task Initialize([NotNull] ApplicationContext applicationContext){return Task.CompletedTask;}public virtual Task Shutdown([NotNull] ApplicationContext applicationContext){return Task.CompletedTask;}public virtual string Name { get; }// 其他代码略...}通过对SilkyModule模块代码定义的分析我们可以得知,一个Silky模块有如下几个作用:

  1. ConfigureServices()方法中,通过IServiceCollection实现服务注册;
  2. RegisterServices()方法中,通过ContainerBuilder实现服务注册;
  3. 在应用程序启动时,通过Initialize()方法实现模块的初始化方法;
  4. 在应用程序停止时,执行Shutdown()方法,可以实现模块资源的释放;
【Silky微服务框架之模块】关于上述第1、2 点的作用, 我们已经在服务引擎一章中做了详细的解析;关于第3、4点的作用,应用程序是如何在启动时调用Initialize()方法或是在停止时执行Shutdown()方法呢?
在构建服务引擎一章中,我们提到,在构建服务引擎时,我们有一项很重要的工作就是注册了InitSilkyHostedService后台任务 。
后台任务InitSilkyHostedService的源码如下所示:
public class InitSilkyHostedService : IHostedService{private readonly IModuleManager _moduleManager;private readonly IHostApplicationLifetime _hostApplicationLifetime;public InitSilkyHostedService(IServiceProvider serviceProvider,IModuleManager moduleManager,IHostApplicationLifetime hostApplicationLifetime){if (EngineContext.Current is SilkyEngine){EngineContext.Current.ServiceProvider = serviceProvider;}_moduleManager = moduleManager;_hostApplicationLifetime = hostApplicationLifetime;}public async Task StartAsync(CancellationToken cancellationToken){Console.WriteLine(@"________/ ____|(_)| || | | (____ | || | __ __\___ \ | || || |/ /| | | |____) || || ||< | |_| | |_____/ |_||_||_|\_\ \__, |__/ ||___/");var version = Assembly.GetExecutingAssembly().GetName().Version;var ver = $"{version.Major}.{version.Minor}.{version.Build}";Console.WriteLine($" :: Silky ::{ver}");_hostApplicationLifetime.ApplicationStarted.Register(async () =>{await _moduleManager.InitializeModules();});}public async Task StopAsync(CancellationToken cancellationToken){_hostApplicationLifetime.ApplicationStopped.Register(async () =>{await _moduleManager.ShutdownModules();});}}
  1. 在后台任务StartAsync(),在打印Silky的banner后,在应用启动时注册一个回调方法,通过模块管理器IModuleManager执行初始化模块方法;
  2. 在后台任务StopAsync(),在应用停止后注册一个回调方法,通过模块管理器IModuleManager执行关闭模块方法,一般用于各个模块的资源释放;
下面,我们查看模块管理器ModuleManager是如何初始化模块的:
public async Task InitializeModules(){foreach (var module in _moduleContainer.Modules){try{Logger.LogInformation("Initialize the module {0}", module.Name);await module.Instance.Initialize(new ApplicationContext(_serviceProvider, _moduleContainer));}catch (Exception e){Logger.LogError($"Initializing the {module.Name} module is an error, reason: {e.Message}");throw;}}}模块容器_moduleContainer的属性_moduleContainer.Modules是通过模块加载器ModuleLoader加载并通过依赖关系进行排序得到的所有模块的实例,我们看到通过foreach对所有的模块实例进行遍历,并依次执行各个模块的Initialize()方法 。
同样的 , 在应用程序停止时,会调用InitSilkyHostedService任务的StopAsync(),该方法通过调用模块管理器的

推荐阅读