Application启动

Asp.net  Core的设计和主要对象

WebHostBuilder:它的责任可以使用哪个监听服务器,使用委托注册中间件,最重要是Webhost

  IWebHostBuilder UseServer(IServer server);
  IWebHostBuilder Configure(Action<IApplicationBuilder> configure);
  WebHost Build();

 HttpContext:面向传输层的服务器负责请求的监听、接收和最终的响应,当它接收到客户端发送的请求后,需要将它分发给后续中间件进行处理,请求在服务器与中间件之间,以及在中间件之间的分发是通过共享上下文的方式实现的,要屏蔽底层Server细节

 

 RequestDelegate:既然针对当前请求的所有输入和输出都通过HttpContext来表示,那么HttpHandler就可以表示成一个Action<HttpContext>对象

MiddleWare:Func<RequestDelegate, RequestDelegate>对象,也就是说它的输入和输出都是一个RequestDelegate

ApplicationBuilder:Use方法用来注册提供的中间件,Build方法则将注册的中间件构建成一个RequestDelegate对象。IApplicationBuilder:主要规格有Use注册RequestDelegate,创建(Build)RequestDelegate,另外还有ApplicationServices(IServiceProvider)、Properties、IFeatureCollection

Server与WebHost的责任将如何划分呢?

WebHost是启动服务器,有个run方法或Start方法,启动是Server,控制权转让

Server的职责:有个启动方法,里面有个while(true){  }方法,如eventloop

服务器会绑定到指定的端口进行请求监听,一旦有请求抵达,服务器会根据该请求创建出代表上下文的HttpContext对象,并将该上下文作为输入调用由所有注册中间件构建而成的RequestDelegate对象。

ABP的设计,基于多模块的设计,AbpModule建立Application基础

它分两步做,相互独立的,它抽象相应的接口,

1、将模块的列表遍历注册服务到容器,分三个阶段PreConfigureServices(预注册)、ConfigureServices(注册)、PostConfigureServices(注册后)。

2,应用的初始化,即将设置服务提供方ServiceProvider,并执行四个生命周期函数,OnPreApplicationInitialization,OnApplicationInitialization、OnPostApplicationInitialization、OnApplicationShutdown

详细:

1、利用AbpApplicationFactory.Create方法,创建一个AbpApplication,它的创建,构建函数就包括填充模块列表、执行第一步服务注册的操作。

2、应用初始化,解决两个问题,服务的提供方ServiceProvider使用是默认的,还是第三方的。其它是执行应用逻辑,即应用的初始化,而应用种类又分为两种,一种是IAbpApplicationWithInternalServiceProvider,另一种是IAbpApplicationWithExternalServiceProvider

第一种,典例是控制台应用,

    public void Initialize()
        {
            ServiceScope = Services.BuildServiceProviderFromFactory().CreateScope();
            SetServiceProvider(ServiceScope.ServiceProvider);            
            InitializeModules();
        }

第二种,ASP.net Core利用IApplicationBuilder以及下面的ApplicationServices

 public void Initialize(IServiceProvider serviceProvider)
        {
            Check.NotNull(serviceProvider, nameof(serviceProvider));

            SetServiceProvider(serviceProvider);

            InitializeModules();
        }
      public static void InitializeApplication([NotNull] this IApplicationBuilder app)
        {
            Check.NotNull(app, nameof(app));

            app.ApplicationServices.GetRequiredService<ObjectAccessor<IApplicationBuilder>>().Value = app;
            app.ApplicationServices.GetRequiredService<IAbpApplicationWithExternalServiceProvider>().Initialize(app.ApplicationServices);
        }

 

Asp.net Core应用

Startup模块负责将各模块内服务注册,定义管道。刚好对应的AbpApplication两步做

注册服务:即创建一个AbpApplication,基于ISerivceCollection刚好定义拓展方法AddApplication

AddApplication方法就是生成应用的实例

AbpApplication职责:abpModule的模块的容器,它包含模块的列表,服务的容器,提供服务,优雅到关闭服务和模块

ConfigureServices最重要的是将模块的服务注册到ServiceCollection里面,为启动服务初始化作准备。

(ConfigureServices(IServiceCollection services),它遍历的Abp模块(注意,模块的依赖关系影响调用的顺序),调用模块的三个生命周期方法。PreConfigureServices、ConfigureServices、PostConfigureServices。

注册管道Configure(IApplicationBuilder):即第二步,即执行模块内应用始化操作,扩展一个InitializeApplication方法进行集成,它的主要功能:

1)设置SetServiceProvider,使用的是AbpAutofacServiceProviderFactory

2)遍历模块的应用生命周期函数。(Startup模块主要配置管道)

  

Asp.net Core下的Startup模块的ConfigureServices的方法,

 public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<AbpModule>();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.InitializeApplication();
        }
    }

 

 3、相关知识点

AbpApplication里的是模块的列表,每个模块又有它的依赖,形成是一个树状的结果,根节点是启动的 AppModule

IAbpModuleDescriptor定义,嵌套,服务配置的上下文的内容

    public interface IAbpModuleDescriptor
    {
        Type Type { get; }
        Assembly Assembly { get; }
        IAbpModule Instance { get; }
        bool IsLoadedAsPlugIn { get; }
        IReadOnlyList<IAbpModuleDescriptor> Dependencies { get; }
    }
  

Abp模块的定义,主要是对应用服务生命状态的描述。

public abstract class AbpModule : 
        IAbpModule,
        IOnPreApplicationInitialization,
        IOnApplicationInitialization,
        IOnPostApplicationInitialization,
        IOnApplicationShutdown, 
        IPreConfigureServices, 
        IPostConfigureServices
 public interface IAbpModule
    {
        void ConfigureServices(ServiceConfigurationContext context);
    }
 

 如何使用第三方提供服务

 public static void UseAutofac(this AbpApplicationCreationOptions options)
        {
            var builder = new ContainerBuilder();
            options.Services.AddObjectAccessor(builder);
            options.Services.AddSingleton((IServiceProviderFactory<ContainerBuilder>) new AbpAutofacServiceProviderFactory(builder));
        }
   public static IHostBuilder UseAutofac(this IHostBuilder hostBuilder)
        {
            var containerBuilder = new ContainerBuilder();

            return hostBuilder.ConfigureServices((_, services) =>
                {
                    services.AddObjectAccessor(containerBuilder);
                })
                .UseServiceProviderFactory(new AbpAutofacServiceProviderFactory(containerBuilder));
        }

 

 AbpApplication主要实现在于抽象类abstract class AbpApplicationBase : IAbpApplication

AddCoreServices方法:注册ASP.net core的 Option,Logging,Location方法

AddCoreAbpServices方法:将IConfiguration替换,注册模块加载,类库存,类型查找,Volo.Abp.Core模块的服务,配置模块4个生命周期方法
      services.TryAddSingleton<IModuleLoader>(moduleLoader);
            services.TryAddSingleton<IAssemblyFinder>(assemblyFinder);
            services.TryAddSingleton<ITypeFinder>(typeFinder);

            services.AddAssemblyOf<IAbpApplication>();

            services.Configure<AbpModuleLifecycleOptions>(options =>
            {
                options.Contributors.Add<OnPreApplicationInitializationModuleLifecycleContributor>();
                options.Contributors.Add<OnApplicationInitializationModuleLifecycleContributor>();
                options.Contributors.Add<OnPostApplicationInitializationModuleLifecycleContributor>();
                options.Contributors.Add<OnApplicationShutdownModuleLifecycleContributor>();
            });
IModuleLoader的方法  LoadModules()方法,包括查找模块,登记模块,注册模块,构建模块集合,按依赖重新排序,调用模块生命周期方法,模块的服务注册,

 // 扫描模块类型,并构建模块描述对象集合。
    var modules = GetDescriptors(services, startupModuleType, plugInSources);
    // 按照模块的依赖性重新排序。
    modules = SortByDependency(modules, startupModuleType);    
    // 调用模块的三个生命周期方法。
    ConfigureServices(modules, services);

ModuleManager管理模块生命周期方法

顺序:

PreConfigureServices、做哪些操作合适,比如rvices.AddConventionalRegistrar

ConfigureServices,主要的服务注册的地方

PostConfigureServices

        {
            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))
            {
                ((IPreConfigureServices)module.Instance).PreConfigureServices(context);
            }

            //ConfigureServices
            foreach (var module in modules)
            {
                if (module.Instance is AbpModule abpModule)
                {
                    if (!abpModule.SkipAutoServiceRegistration)
                    {
                        services.AddAssembly(module.Type.Assembly);
                    }
                }

                module.Instance.ConfigureServices(context);
            }

            //PostConfigureServices
            foreach (var module in modules.Where(m => m.Instance is IPostConfigureServices))
            {
                ((IPostConfigureServices)module.Instance).PostConfigureServices(context);
            }

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

 一个模块有 4 个生命周期,它们都是在抽象基类 AbpModule 当中定义的,分别是 预加载、初始化、初始化完成、销毁。前三个生命周期是依次执行的 预加载->初始化->初始化完成,而最后一个销毁动作则是在程序终止的时候,通过 AbpModuleManager 遍历模块,调用其 ShutDown() 方法进行销毁动作。

  Application初始化 Initialize,

定义一个接口,依赖外部IServiceProvider的AbpApplication。首先设置IServiceProvider,再执行相关模块化的相关操作

  public interface IAbpApplicationWithExternalServiceProvider : IAbpApplication
    {
        void Initialize([NotNull] IServiceProvider serviceProvider);
    }

注意IServiceProvider是谁提供,默认还是 AutoFac提供,AbpApplicationWithExternalServiceProvider是在注册Server时,UseServiceProviderFactory进行替换

AbpApplicationWithInternalServiceProvider,这里Initialize并没有传值ServiceProvider

    public void Initialize()
        {
            ServiceScope = Services.BuildServiceProviderFromFactory().CreateScope();
            SetServiceProvider(ServiceScope.ServiceProvider);            
            InitializeModules();
        }
BuildServiceProviderFromFactory,查找到IServiceProviderFactory,=》AbpAutofacServiceProviderFactory
创建ContainerBuilder,注册服务到autofac,返回IServiceProvider,
这里的SetServiceProvider方法,一个是给Application,另一个是容器
 protected virtual void SetServiceProvider(IServiceProvider serviceProvider)
        {
            ServiceProvider = serviceProvider;
            ServiceProvider.GetRequiredService<ObjectAccessor<IServiceProvider>>().Value = ServiceProvider;
        }
InitializeModules使用ModuleManager
  public void InitializeModules(ApplicationInitializationContext context)
        {
            LogListOfModules();

            foreach (var Contributor in _lifecycleContributors)
            {
                foreach (var module in _moduleContainer.Modules)
                {
                    Contributor.Initialize(context, module.Instance);
                }
            }

            _logger.LogInformation("Initialized all ABP modules.");
        }
模块级别与应用级别的生命周期有什么不同
框架模块是框架的核心模块,其模块的逻辑与处理基本都在传统的三个生命周期进行处理。在我们的 services.AddApplication() 阶段就已经完成所有初始化,
可以给 应用程序模块 提供服务
第二种则是 应用程序模块,这种模块则是实现了特定的业务/功能,例如身份管理、租户管理等,而新增加的四个生命周期基本是为这种类型的模块服务的。
IOnPreApplicationInitializationIOnApplicationInitializationIOnPostApplicationInitializationIOnApplicationShutdown

 2、注册的规约有哪些,如何自定义,在哪里注入   DefaultConventionalRegistrar

 

理解ObjectAccessor,添加一个空的对象访问器,该访问器的值会在初始化的时候被赋值,例如在上文当中的 IServiceProvider 通过 ObjectAccessor<T> 对象包裹起来,其值是 NULL,但是在后面我们可以根据自己的需要替换其具体的 Value 另外知识点,out,in 协变和逆变

           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 = LoadModules(services, options);




 

posted on 2019-10-31 01:52  dollymi  阅读(1445)  评论(0编辑  收藏  举报

导航