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()
阶段就已经完成所有初始化,
可以给 应用程序模块 提供服务
第二种则是 应用程序模块,这种模块则是实现了特定的业务/功能,例如身份管理、租户管理等,而新增加的四个生命周期基本是为这种类型的模块服务的。
IOnPreApplicationInitialization
、IOnApplicationInitialization
、IOnPostApplicationInitialization
、IOnApplicationShutdown
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);