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



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM