原文:.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. 初识Pyhon之准备环境

    安装成功python的运行环境之后,你可能要迫不及待大展身手了 如果你有一定的语言基础,那么基础这一块儿就可以简单的看看就可以了,但是你是一个编程语言的初学者.不着急,慢慢往下看 打开pycharm创 ...

  2. PAT Basic 1027

    1027 打印沙漏 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号:各行 ...

  3. Handler处理器和自定义Opener

    Handler处理器 和 自定义Opener opener是 urllib2.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的opener(也就是模块帮我们构 ...

  4. lucene segment的产生,flush, commit与es的refresh,flush

    1 segment的产生 当索引一个文档时,如果存在空闲的segment(未被其他线程锁定),则取出空闲segment list中的最后一个segment(LIFO),并锁定,将文档索引至该segme ...

  5. Virtualbox虚拟机相关

    Virtualbox虚拟机相关 Virtualbox是我一直使用的虚拟机,由于需要一些测试环境等,会经常使用多个虚拟机.经常捣腾.之前有涉及到一些virtualbox方面的问题的处理,并没有记录下来, ...

  6. Python requests模块params、data、json的区别

    json和dict对比 json的key只能是字符串,python的dict可以是任何可hash对象(hashtable type): json的key可以是有序.重复的:dict的key不可以重复. ...

  7. Ubuntu Software Center has closed unexpectly解决方案

    打开软件中心Ubuntu Software Center的时候 出现crash report :The application Ubuntu Software Center has closed un ...

  8. python pdb模块

    参考文件http://pythonconquerstheuniverse.wordpress.com/category/Python-debugger/ 翻译不是一一对应 Debug功能对于devel ...

  9. Educational Codeforces Round 26

    Educational Codeforces Round 26 困到不行的场,等着中午显示器到了就可以美滋滋了 A. Text Volume time limit per test 1 second ...

  10. NBOJv2——Problem 1002: 蛤玮的财宝(多线程DP)

    Problem 1002: 蛤玮的财宝 Time Limits:  1000 MS   Memory Limits:  65536 KB 64-bit interger IO format:  %ll ...