ABP源码分析 - 服务配置(1)

比较随意,记录下过程,以便忘了以后重拾。

三个关注点

Program.cs

      internal static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .UseAutofac() // 第一个关注点
        .UseSerilog();
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<AuthCenterWebModule>(); // 第二个关注点
        }

        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
        {
            app.InitializeApplication(); // 第三个关注点
        }
    }

 

services.AddApplication()过程

        public static IAbpApplicationWithExternalServiceProvider AddApplication<TStartupModule>(
            [NotNull] this IServiceCollection services, 
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
            where TStartupModule : IAbpModule
        {
            // Factory工厂创建AbpApplication
            return AbpApplicationFactory.Create<TStartupModule>(services, optionsAction);
        }
        public static IAbpApplicationWithExternalServiceProvider Create<TStartupModule>(
            [NotNull] IServiceCollection services,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
            where TStartupModule : IAbpModule
        {
            return Create(typeof(TStartupModule), services, optionsAction);
        }

        public static IAbpApplicationWithExternalServiceProvider Create(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction = null)
        {
            // 这里创建具体实例
            return new AbpApplicationWithExternalServiceProvider(startupModuleType, services, optionsAction);
        }

 
查看AbpApplicationWithExternalServiceProvider构造函数

        public AbpApplicationWithExternalServiceProvider(
            [NotNull] Type startupModuleType, 
            [NotNull] IServiceCollection services, 
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction
            ) : base(
                startupModuleType, 
                services, 
                optionsAction)
        {
            // 注入自己,初始化在基类,继续查看基类
            services.AddSingleton<IAbpApplicationWithExternalServiceProvider>(this);
        }
        internal AbpApplicationBase(
            [NotNull] Type startupModuleType,
            [NotNull] IServiceCollection services,
            [CanBeNull] Action<AbpApplicationCreationOptions> optionsAction)
        {
            Check.NotNull(startupModuleType, nameof(startupModuleType));
            Check.NotNull(services, nameof(services));

            StartupModuleType = startupModuleType;
            Services = services;

            services.TryAddObjectAccessor<IServiceProvider>();

            var options = new AbpApplicationCreationOptions(services);
            optionsAction?.Invoke(options);

            services.AddSingleton<IAbpApplication>(this);
            services.AddSingleton<IModuleContainer>(this);

            services.AddCoreServices();
            services.AddCoreAbpServices(this, options);

            // 以上都是注入服务

            // 加载模块,Modules的模块是按依赖顺序的排序
            Modules = LoadModules(services, options);
            // 主要看这里,服务配置
            ConfigureServices();
        }
        protected virtual void ConfigureServices()
        {
            // 将ServiceCollection传入ServiceConfigurationContext
            var context = new ServiceConfigurationContext(Services);
            Services.AddSingleton(context);

            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    // 为每个模块实例设定context, 这样通过每个模块通过上下文都可以访问ServiceCollection
                    abpModule.ServiceConfigurationContext = context;
                }
            }

            // 依次调用每个模块的PreConfigureServices, ConfigureServices, PostConfigureServices

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

            //ConfigureServices
            foreach (var module in Modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    // 执行约定注入
                    if (!abpModule.SkipAutoServiceRegistration)
                    {
                        Services.AddAssembly(module.Type.Assembly);
                    }
                }

                try
                {
                    module.Instance.ConfigureServices(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IAbpModule.ConfigureServices)} 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
                {
                    ((IPostConfigureServices)module.Instance).PostConfigureServices(context);
                }
                catch (Exception ex)
                {
                    throw new AbpInitializationException($"An error occurred during {nameof(IPostConfigureServices.PostConfigureServices)} 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;
                }
            }
        }

小结

以上实现了每个模块服务的注入,即所有模块执行PreConfigureServices,完成后所有模块执行ConfigureServices,完成后所有模块执行PostConfigureServices。
PreConfigureServices即服务注入还没开始,这里可以做些什么?
ConfigureServices注入,
PostConfigureServices所有服务已注入,这里可以做些什么?

    public class AuthCenterDomainModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
           
        }

        public override void ConfigureServices(ServiceConfigurationContext context)
        {

        }

        public override void PostConfigureServices(ServiceConfigurationContext context)
        {
            
        }
    }

posted @ 2021-01-16 20:49  pojianbing  阅读(392)  评论(0编辑  收藏  举报