原文:.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. 【图论 动态规划拆点】luoguP3953 逛公园

    经典的动态规划拆点问题. 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 NN 个点 MM 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, NN 号点是公园的出口,每条边有一个非负 ...

  2. DNS服务-主从架构搭建

    为了网站的可靠性,通常都会有多个DNS服务器,万一DNS服务器宕机了,可以实现DNS服务器容错 通常都会有一个主DNS服务器,后面配若干个辅助DNS服务器,这个主DNS服务器的数据库会同步给其他的DN ...

  3. ES5中新增的forEach等新方法的一些使用声明

    转载地址:http://www.zhangxinxu.com/wordpress/?p=3220 一.前言-索引 ES5中新增的不少东西,了解之对我们写JavaScript会有不少帮助,比如数组这块, ...

  4. 文件的软硬链接& 文件编辑vi和vim

    目录 文件的软硬链接 1.软链接 2.硬链接 文件编辑vi和vim 须先安装vim命令的软件包yum install -y vim 三种模式: 1.普通模式 2.编辑模式 3.末行模式 文件的软硬链接 ...

  5. vmalloc_init

    /* linux/mm/vmalloc.c*/ struct vmap_area { unsigned long va_start; unsigned long va_end; unsigned lo ...

  6. Cocos2D 添加 UIView

    cocos2d是使用继承于ccnode的结点类型的层.但是我想用一个opengl来绘制,就简单的情况来说必须得加一个uiview.现转载如下: 第一部分:: 使用Cocos2D开发游戏和应用程序的时候 ...

  7. MIP启发式求解:局部搜索 (local search)

    *本文主要记录和分享学习到的知识,算不上原创. *参考文献见链接. 本文讲述的是求解MIP问题的启发式算法. 启发式算法的目的在于短时间内获得较优解. 个人认为局部搜索(local search)几乎 ...

  8. POJ 2486 树形背包DP Apple Tree

    设d(u, j, 0)表示在以u为根的子树中至多走k步并且最终返回u,能吃到的最多的苹果. 则有状态转移方程: #include <iostream> #include <cstdi ...

  9. PYDay5- 数据类型set、三元运算、函数

    1.set set集合,是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object se ...

  10. 自定义iOS上双击Home键图切换

    如果双击Home,会来到iOS App的switcher页面,在这儿列出了当前系统挂起的App, 上面有每个App的切屏,相信大家都熟悉这个东东了.它其实是每个App在挂起前,对App后个载屏. 那么 ...