原文:.net core mvc启动顺序以及主要部件2

前一篇提到WebHost.CreateDefaultBuilder(args)方法创建了WebHostBuilder实例,WebHostBuilder实例有三个主要功能 1、构建了IConfiguration实例和基础环境配置,2、构建了IServiceCollection服务,也就是依赖注入的容器,3、创建了webhost实例,这个webhost就是我们的接收请求的第一个管道,其中暴露出来的主要方法Build,请看源代码:

 public IWebHost Build()
{
if (!_webHostBuilt)
{
_webHostBuilt = true;
AggregateException hostingStartupErrors;
IServiceCollection serviceCollection = BuildCommonServices(out hostingStartupErrors);
IServiceCollection serviceCollection2 = serviceCollection.Clone();
IServiceProvider hostingServiceProvider = _003CBuild_003Eg__GetProviderFromFactory_007C13_0(serviceCollection);
if (!_options.SuppressStatusMessages)
{
if (Environment.GetEnvironmentVariable("Hosting:Environment") != null)
{
Console.WriteLine("The environment variable 'Hosting:Environment' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
}
if (Environment.GetEnvironmentVariable("ASPNET_ENV") != null)
{
Console.WriteLine("The environment variable 'ASPNET_ENV' is obsolete and has been replaced with 'ASPNETCORE_ENVIRONMENT'");
}
if (Environment.GetEnvironmentVariable("ASPNETCORE_SERVER.URLS") != null)
{
Console.WriteLine("The environment variable 'ASPNETCORE_SERVER.URLS' is obsolete and has been replaced with 'ASPNETCORE_URLS'");
}
}
AddApplicationServices(serviceCollection2, hostingServiceProvider);
WebHost webHost = new WebHost(serviceCollection2, hostingServiceProvider, _options, _config, hostingStartupErrors);
try
{
webHost.Initialize();
ILogger<WebHost> requiredService = webHost.Services.GetRequiredService<ILogger<WebHost>>();
foreach (IGrouping<string, string> item in from g in _options.GetFinalHostingStartupAssemblies().GroupBy((string a) => a, StringComparer.OrdinalIgnoreCase)
where g.Count() >
select g)
{
requiredService.LogWarning($"The assembly {item} was specified multiple times. Hosting startup assemblies should only be specified once.");
}
return webHost;
}
catch
{
webHost.Dispose();
throw;
}
}
throw new InvalidOperationException(Resources.WebHostBuilder_SingleInstance);
}

这个方法中有几个笔记重要的部分,下面我给标记一下

调用BuildCommonServices私有方法主要是注入一些程序所需的基础组件,请看源代码:

  private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
{
hostingStartupErrors = null;
_options = new WebHostOptions(_config, Assembly.GetEntryAssembly()?.GetName().Name);
if (!_options.PreventHostingStartup)
{
List<Exception> list = new List<Exception>();
foreach (string item in _options.GetFinalHostingStartupAssemblies().Distinct(StringComparer.OrdinalIgnoreCase))
{
try
{
foreach (HostingStartupAttribute customAttribute in Assembly.Load(new AssemblyName(item)).GetCustomAttributes<HostingStartupAttribute>())
{
((IHostingStartup)Activator.CreateInstance(customAttribute.HostingStartupType)).Configure(this);
}
}
catch (Exception innerException)
{
list.Add(new InvalidOperationException("Startup assembly " + item + " failed to execute. See the inner exception for more details.", innerException));
}
}
if (list.Count > )
{
hostingStartupErrors = new AggregateException(list);
}
}
string contentRootPath = ResolveContentRootPath(_options.ContentRootPath, AppContext.BaseDirectory);
_hostingEnvironment.Initialize(contentRootPath, _options);
_context.HostingEnvironment = _hostingEnvironment;
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton(_options);
((IServiceCollection)serviceCollection).AddSingleton((IHostingEnvironment)_hostingEnvironment);
((IServiceCollection)serviceCollection).AddSingleton((Microsoft.Extensions.Hosting.IHostingEnvironment)_hostingEnvironment);
serviceCollection.AddSingleton(_context);
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder().SetBasePath(_hostingEnvironment.ContentRootPath).AddConfiguration(_config);
foreach (Action<WebHostBuilderContext, IConfigurationBuilder> configureAppConfigurationBuilderDelegate in _configureAppConfigurationBuilderDelegates)
{
configureAppConfigurationBuilderDelegate(_context, configurationBuilder);
}
IConfigurationRoot configurationRoot = configurationBuilder.Build();
((IServiceCollection)serviceCollection).AddSingleton((IConfiguration)configurationRoot);
_context.Configuration = configurationRoot;
DiagnosticListener implementationInstance = new DiagnosticListener("Microsoft.AspNetCore");
serviceCollection.AddSingleton(implementationInstance);
((IServiceCollection)serviceCollection).AddSingleton((DiagnosticSource)implementationInstance);
serviceCollection.AddTransient<IApplicationBuilderFactory, ApplicationBuilderFactory>();
serviceCollection.AddTransient<IHttpContextFactory, HttpContextFactory>();
serviceCollection.AddScoped<IMiddlewareFactory, MiddlewareFactory>();
serviceCollection.AddOptions();
serviceCollection.AddLogging();
serviceCollection.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
serviceCollection.AddTransient<IServiceProviderFactory<IServiceCollection>, DefaultServiceProviderFactory>();
serviceCollection.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
if (!string.IsNullOrEmpty(_options.StartupAssembly))
{
try
{
Type startupType = StartupLoader.FindStartupType(_options.StartupAssembly, _hostingEnvironment.EnvironmentName);
if (IntrospectionExtensions.GetTypeInfo(typeof(IStartup)).IsAssignableFrom(startupType.GetTypeInfo()))
{
serviceCollection.AddSingleton(typeof(IStartup), startupType);
}
else
{
serviceCollection.AddSingleton(typeof(IStartup), delegate (IServiceProvider sp)
{
IHostingEnvironment requiredService = sp.GetRequiredService<IHostingEnvironment>();
return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, requiredService.EnvironmentName));
});
}
}
catch (Exception source)
{
ExceptionDispatchInfo capture = ExceptionDispatchInfo.Capture(source);
((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, IStartup>)delegate
{
capture.Throw();
return null;
});
}
}
foreach (Action<WebHostBuilderContext, IServiceCollection> configureServicesDelegate in _configureServicesDelegates)
{
configureServicesDelegate(_context, serviceCollection);
}
return serviceCollection;
}

这个方法中其中就包含了注入IConfiguration的代码和构建IServiceCollection容器的代码,当然还有一些其他的主要中间件注入啊IApplicationBuilderFactory,包括HttpContextFactory等等都在这个方法里面被IServiceCollection容器管理,具体请看下图

这里讲清楚之后,我们直接进入UseStartup方法中,这个方法是注入了Startup的实例,请看主要源代码

 public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType)
{
string name = startupType.GetTypeInfo().Assembly.GetName().Name;
return hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, name).ConfigureServices(delegate (IServiceCollection services)
{
if (IntrospectionExtensions.GetTypeInfo(typeof(IStartup)).IsAssignableFrom(startupType.GetTypeInfo()))
{
services.AddSingleton(typeof(IStartup), startupType);
}
else
{
services.AddSingleton(typeof(IStartup), delegate (IServiceProvider sp)
{
IHostingEnvironment requiredService = sp.GetRequiredService<IHostingEnvironment>();
return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, requiredService.EnvironmentName));
});
}
});
}

上面只是被IServiceCollection所管理  并没有真正起作用,真正调用的是Main方法中的Build().Run(),这里的Build就是上面那个IWebHostBuilder中的主要的构建方法,而Run则是正式启动应用程序和调用Startup中的ConfigureServices方法

请看代码:

分享Program类的过程大致就到这里了

.net core mvc启动顺序以及主要部件2的更多相关文章

  1. .net core mvc启动顺序以及主要部件1

    原文:.net core mvc启动顺序以及主要部件1 首先我是新人一个写这些东西也是为了增加记忆,有不对的地方请多多指教. 说回正题,打开Program.cs文件,看到在有个CrateWebHost ...

  2. .net core mvc启动顺序以及主要部件4-MVC

    前面三章已经把MVC启动过程以及源代码做了讲解,本章开始正式MVC,mvc全称叫model view controller,也就是把表现层又细分三层,官网的图片描述: 默认创建了一个.net core ...

  3. .net core mvc启动顺序以及主要部件3-Startup

    前面分享了.net core Program类的启动过程已经源代码介绍,这里将继续讲Startup类中的两个约定方法,一个是ConfigureServices,这个方法是用来写我们应用程序所依赖的组件 ...

  4. PCB MVC启动顺序与各层之间数据传递对象关系

    准备着手基于MVC模式写一套Web端流程指示查看,先着手开发WebAPI打通数据接口,后续可扩展手机端 这里将MVC基本关系整理如下: 一.MVC启动顺序 二.MVC各层之间数据传递对象关系

  5. ASP.NET Core MVC 源码学习:MVC 启动流程详解

    前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...

  6. asp.net core mvc剖析:启动流程

    asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghelper,viewcomponent,D ...

  7. 解说asp.net core MVC 过滤器的执行顺序

    asp.net core MVC 过滤器会在请求管道的各个阶段触发.同一阶段又可以注册多个范围的过滤器,例如Global范围,controller范围等.以ActionFilter为例,我们来看看过滤 ...

  8. linux下使用supervisor启动.net core mvc website的配置

    发布好的asp.net core mvc项目, 如果想在window或linux下的以控制台程序启动的话,可以用下面的命令 dotnet MyProject.dll --urls="http ...

  9. net core mvc剖析:启动流程

    net core mvc剖析:启动流程 asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghe ...

随机推荐

  1. Zookeeper 集群 BindException: Cannot assign requested address 解决方案

    前言 经历: 最近在搭建zookeeper集群,基础是3台机器(尝试过ubuntu 17 和 Centos 7). 一开始选择的是3台腾讯云服务器,每台机器在java环境配置正确的情况下,单机的情况都 ...

  2. perl学习二:简单变量

    字符串变量:${}1.单引号:不进行变量替换,不进行转义,字符串可以跨行.2.双引号:变量替换(贪婪匹配原则).支持转义字符(转义字符可以另外看)3.反引号 字符串的特殊表示方法:qq(...) q( ...

  3. python+ selenium 实现简历自动刷新

    本文用到的文件的下载地址 百度网盘链接: https://pan.baidu.com/s/1wIda-wUz4X_Ck72xgZ6Ddg 提取码: etaa 1 安装Python 和 selenium ...

  4. 安装tesserocr的步骤和报错RuntimeError: Failed to init API, possibly an invalid tessdata path解决办法

    1,首先下载合适的tesseract-ocr的版本 2,然后安装到这一步注意要勾选这一项来安装OCR识别支持的语言包,这样OCR就可以识别多国语言,然后就可以一直点击下一步完成安装. 3,安装tess ...

  5. Python字符串操作详解

    菜鸟学Python第五天 流程控制 for循环 while循环 VS for循环: while循环:称之为条件循环,循环的次数取决于条件何时为false for循环:称之为迭代器循环,循环的次数取决于 ...

  6. IntelliJ IDEA 类和方法注释的生成以及Javadoc的简单使用记录

    idea,设置类注释和,方法注释的常见的设置方法(不同的版本设置方法有所偏差,简单记录一些目前自己在使用的方法,) 方法注释:在keyMap中搜索Fix doc comment ,后点击右键设置一个快 ...

  7. 【LeetCode】Maximize Sum Of Array After K Negations(K 次取反后最大化的数组和)

    这道题是LeetCode里的第1005道题. 题目描述: 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次. ...

  8. 刷题总结——小z的袜子(bzoj2038)

    题目: Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把 ...

  9. 【DFS序+树状数组】BNUOJ 52733 Random Numbers

    http://acm.bnu.edu.cn/v3/problem_show.php?pid=52733 [题意] 给定一棵树,这棵树每个点都有一个点权,标号从0开始,0是根结点 修改操作: SEED ...

  10. 无记录时显示gridview表头,并增加一行显示“没有记录”【绑定SqlDataSource控件时】

    原文发布时间为:2008-08-04 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...