.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的更多相关文章
- .net core mvc启动顺序以及主要部件1
原文:.net core mvc启动顺序以及主要部件1 首先我是新人一个写这些东西也是为了增加记忆,有不对的地方请多多指教. 说回正题,打开Program.cs文件,看到在有个CrateWebHost ...
- .net core mvc启动顺序以及主要部件4-MVC
前面三章已经把MVC启动过程以及源代码做了讲解,本章开始正式MVC,mvc全称叫model view controller,也就是把表现层又细分三层,官网的图片描述: 默认创建了一个.net core ...
- .net core mvc启动顺序以及主要部件3-Startup
前面分享了.net core Program类的启动过程已经源代码介绍,这里将继续讲Startup类中的两个约定方法,一个是ConfigureServices,这个方法是用来写我们应用程序所依赖的组件 ...
- PCB MVC启动顺序与各层之间数据传递对象关系
准备着手基于MVC模式写一套Web端流程指示查看,先着手开发WebAPI打通数据接口,后续可扩展手机端 这里将MVC基本关系整理如下: 一.MVC启动顺序 二.MVC各层之间数据传递对象关系
- ASP.NET Core MVC 源码学习:MVC 启动流程详解
前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...
- asp.net core mvc剖析:启动流程
asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghelper,viewcomponent,D ...
- 解说asp.net core MVC 过滤器的执行顺序
asp.net core MVC 过滤器会在请求管道的各个阶段触发.同一阶段又可以注册多个范围的过滤器,例如Global范围,controller范围等.以ActionFilter为例,我们来看看过滤 ...
- linux下使用supervisor启动.net core mvc website的配置
发布好的asp.net core mvc项目, 如果想在window或linux下的以控制台程序启动的话,可以用下面的命令 dotnet MyProject.dll --urls="http ...
- net core mvc剖析:启动流程
net core mvc剖析:启动流程 asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghe ...
随机推荐
- PAT 乙级 1019
题目 题目地址:PAT 乙级 1019 思路 本题没有考虑到小于1000的情况,当小于1000的时需要给vector的向量中推入0,直到向量中有四位数字,之后再进行排序并进行相关计算 代码 #incl ...
- 用python实现自动玩21点小游戏
1. 背景 前段时间发现一个论坛上(https://npupt.com/blackjack.php)有21点小游戏. 这个21点小游戏的规则是每个人开局都会获得随机点数,如果觉得点数小,可以继续摸牌. ...
- Redis数据库(一)
1. Redis简介 Redis是非关系型数据库(nosql),数据保存在内存中,安全性低,但读取速度快. Redis主要存储变化较快且数据不是特别重要的数据. Redis是一个key-value存储 ...
- 主DNS服务-正向解析
环境 准备最少两台主机 一台当DNS服务器,一台当客户机 如:192.168.43.7这台主机当DNS服务器,192.168.43.6这台主机当客户机 安装DNS服务 yum install -y b ...
- 搭建pip源
1.安装pip软件 yum -y install python-pippip install --upgrade pippip install pip2pi 2.安装apacheyum -y inst ...
- 【Charles】使用Charles时,抓不到包的情况。
有可能是因为浏览器的代理权限给了其他插件,需要停用该插件,重启浏览器,重新进行访问就可以看到Charles的抓包信息了.
- HTML 文件类表单元素如何限制上传类型,Accept属性设置
需求描述:简单的控制file的选择类型 解决方法:使用HTML input file 的accept属性控制 实例: <form action="demo_form.asp" ...
- 【php】 布尔值判断
当转换为 boolean 时,以下值被认为是 FALSE: 布尔值 FALSE 本身 整型值 0(零) 浮点型值 0.0(零) 空字符串,以及字符串 "0" 不包括任何元素的数组 ...
- 在myeclipse中使用查找功能
1.全局搜索(快捷键:ctrl+H) 在弹出对话框中选File Search选项,然后在第一个文本框中粘贴(我一般用粘贴)或自已手动录入(容易写错)要查找的字符串(可以是英文字符也可以是汉字),在第二 ...
- php在字符串中替换多个字符
php替换多个字符串str_replace函数 echo str_replace(array("m","i"),array("n",&quo ...