• 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);
    
    



  • 相关阅读:
    CSS定位(Position)
    深入理解Javascript闭包(二)
    深入理解Javascript闭包(一)
    如何将页脚固定在页面底部
    JQuery中$.fn的用法示例
    关于HttpWebRequest.KeepAlive
    Fiddler 教程
    js数组的操作
    oracle 修改字段类型的方法(转)
    Oracle查看表结构的几种方法(转后加工)
  • 原文地址:https://www.cnblogs.com/cloudsu/p/11766557.html
Copyright © 2020-2023  润新知