谈心 发表于 2023-9-25 22:58:34

Abp vNext 模块加载机制

文章目录
生命周期


[*]PreConfigureServices添加依赖注入或者其它配置之前
[*]ConfigureServices 添加依赖注入或者其它配置
[*]PostConfigureServices 添加依赖注入或者其它配置之后
[*]OnPreApplicationInitialization 初始化所有模块之前
[*]OnApplicationInitialization 初始化所有模块
[*]OnPostApplicationInitialization 初始化所有模块之后
[*]OnApplicationShutdown 应用关闭执行
OnPreApplicationInitialization和OnPostApplicationInitialization方法用来在OnApplicationInitialization之前或之后覆盖和编写你的代码.请注意,在这些方法中编写的代码将在所有其他模块的OnApplicationInitialization方法之前/之后执行.
加载流程


[*]进入到Startup
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddApplication<xxxManagementHttpApiHostModule>();
    }
}
[*]查看AddApplication源码会调用AbpApplicationFactory.CreateAsync
public async static Task<IAbpApplicationWithExternalServiceProvider> CreateAsync(
    Type startupModuleType,
    IServiceCollection services,
    Action<AbpApplicationCreationOptions>? optionsAction = null)
{
    var app = new AbpApplicationWithExternalServiceProvider(startupModuleType, services, options =>
    {
      options.SkipConfigureServices = true;
      optionsAction?.Invoke(options);
    });
    await app.ConfigureServicesAsync();
    return app;
}
[*]进入AbpApplicationWithExternalServiceProvider,我们可以看到继承AbpApplicationBase
internal class AbpApplicationWithExternalServiceProvider : AbpApplicationBase, IAbpApplicationWithExternalServiceProvider
{
    public AbpApplicationWithExternalServiceProvider(
       Type startupModuleType,
       IServiceCollection services,
      Action<AbpApplicationCreationOptions>? optionsAction
      ) : base(
            startupModuleType,
            services,
            optionsAction)
    {
      services.AddSingleton<IAbpApplicationWithExternalServiceProvider>(this);
    }

    void IAbpApplicationWithExternalServiceProvider.SetServiceProvider( IServiceProvider serviceProvider)
    {
      Check.NotNull(serviceProvider, nameof(serviceProvider));

      // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
      if (ServiceProvider != null)
      {
            if (ServiceProvider != serviceProvider)
            {
                throw new AbpException("Service provider was already set before to another service provider instance.");
            }

            return;
      }

      SetServiceProvider(serviceProvider);
    }
[*]查看AbpApplicationBase构造函数
internal AbpApplicationBase(
       Type startupModuleType,
       IServiceCollection services,
      Action<AbpApplicationCreationOptions>? optionsAction)
    {
      services.AddCoreServices();
      services.AddCoreAbpServices(this, options);
      // 加载模块
      Modules = LoadModules(services, options);
    }
[*]查看加载模块逻辑
public IAbpModuleDescriptor[] LoadModules(
    IServiceCollection services,
    Type startupModuleType,
    PlugInSourceList plugInSources)
{
    Check.NotNull(services, nameof(services));
    Check.NotNull(startupModuleType, nameof(startupModuleType));
    Check.NotNull(plugInSources, nameof(plugInSources));
    // 扫描模块
    var modules = GetDescriptors(services, startupModuleType, plugInSources);
    // 按照模块的依赖性重新排序
    modules = SortByDependency(modules, startupModuleType);
    return modules.ToArray();
}生命周期

在上面第二步我们可以看到有一个await app.ConfigureServicesAsync();

[*]在这个方法中可以看到依次执行每个模块的PreConfigureServices,ConfigureServices,PostConfigureServices
public virtual async Task ConfigureServicesAsync()
    {
      CheckMultipleConfigureServices();

      var context = new ServiceConfigurationContext(Services);
      Services.AddSingleton(context);

      foreach (var module in Modules)
      {
            if (module.Instance is AbpModule abpModule)
            {
                abpModule.ServiceConfigurationContext = context;
            }
      }

      //PreConfigureServices
      foreach (var module in Modules.Where(m => m.Instance is IPreConfigureServices))
      {
            try
            {
                await ((IPreConfigureServices)module.Instance).PreConfigureServicesAsync(context);
            }
            catch (Exception ex)
            {
                throw new AbpInitializationException($"An error occurred during {nameof(IPreConfigureServices.PreConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
            }
      }

      var assemblies = new HashSet<Assembly>();

      //ConfigureServices
      foreach (var module in Modules)
      {
            if (module.Instance is AbpModule abpModule)
            {
                if (!abpModule.SkipAutoServiceRegistration)
                {
                  var assembly = module.Type.Assembly;
                  if (!assemblies.Contains(assembly))
                  {
                        Services.AddAssembly(assembly);
                        assemblies.Add(assembly);
                  }
                }
            }

            try
            {
                await module.Instance.ConfigureServicesAsync(context);
            }
            catch (Exception ex)
            {
                throw new AbpInitializationException($"An error occurred during {nameof(IAbpModule.ConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
            }
      }

      //PostConfigureServices
      foreach (var module in Modules.Where(m => m.Instance is IPostConfigureServices))
      {
            try
            {
                await ((IPostConfigureServices)module.Instance).PostConfigureServicesAsync(context);
            }
            catch (Exception ex)
            {
                throw new AbpInitializationException($"An error occurred during {nameof(IPostConfigureServices.PostConfigureServicesAsync)} phase of the module {module.Type.AssemblyQualifiedName}. See the inner exception for details.", ex);
            }
      }

      foreach (var module in Modules)
      {
            if (module.Instance is AbpModule abpModule)
            {
                abpModule.ServiceConfigurationContext = null!;
            }
      }

      _configuredServices = true;
    }

[*]再次查看第四步中有一个services.AddCoreAbpServices(this, options);
这个里面构造好其它的四个生命周期
internal static void AddCoreAbpServices(this IServiceCollection services,
    IAbpApplication abpApplication,
    AbpApplicationCreationOptions applicationCreationOptions)
{
    var moduleLoader = new ModuleLoader();
    var assemblyFinder = new AssemblyFinder(abpApplication);
    var typeFinder = new TypeFinder(assemblyFinder);
    if (!services.IsAdded<IConfiguration>())
    {
      services.ReplaceConfiguration(
            ConfigurationHelper.BuildConfiguration(
                applicationCreationOptions.Configuration
            )
      );
    }
    services.TryAddSingleton<IModuleLoader>(moduleLoader);
    services.TryAddSingleton<IAssemblyFinder>(assemblyFinder);
    services.TryAddSingleton<ITypeFinder>(typeFinder);
    services.TryAddSingleton<IInitLoggerFactory>(new DefaultInitLoggerFactory());
    services.AddAssemblyOf<IAbpApplication>();
    services.AddTransient(typeof(ISimpleStateCheckerManager<>), typeof(SimpleStateCheckerManager<>));
    // 注册生命周期
    services.Configure<AbpModuleLifecycleOptions>(options =>
    {
      // OnPreApplicationInitialization
      options.Contributors.Add<OnPreApplicationInitializationModuleLifecycleContributor>();
      // OnApplicationInitialization
      options.Contributors.Add<OnApplicationInitializationModuleLifecycleContributor>();
      // OnPostApplicationInitialization
      options.Contributors.Add<OnPostApplicationInitializationModuleLifecycleContributor>();
      // OnApplicationShutdown
      options.Contributors.Add<OnApplicationShutdownModuleLifecycleContributor>();
    });
}注册了这四个生命周期,在什么时候调用呢?请继续往下看。

[*]继续回到Startup类
public class Startup
{
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
      app.InitializeApplication();
    }
}
[*]查看InitializeApplication


[*]遍历刚刚注入的四个生命周期,执行Initialize初始化方法
public void InitializeModules(ApplicationInitializationContext context)
{
    foreach (var contributor in _lifecycleContributors)
    {
      foreach (var module in _moduleContainer.Modules)
      {
            try
            {
                contributor.Initialize(context, module.Instance);
            }
            catch (Exception ex)
            {
                //
            }
      }
    }
    _logger.LogInformation("Initialized all ABP modules.");
}Abp vNext Pro


[*]Abp Vnext Pro Github地址 的 Vue3 实现版本 开箱即用的中后台前端/设计解决方案.
[*]文档地址
[*]演示地址:用户名admin 密码1q2w3E*
[*]Abp Vnext Pro Suite Github地址 代码生成器。
[*]演示地址:用户名admin 密码1q2w3E*
[*]视频教程
如果觉得可以,不要吝啬你的小星星哦

文章目录

来源:https://www.cnblogs.com/WangJunZzz/archive/2023/09/25/17728392.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Abp vNext 模块加载机制