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

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

 1 public IWebHost Build()
 2         {
 3             if (!_webHostBuilt)
 4             {
 5                 _webHostBuilt = true;
 6                 AggregateException hostingStartupErrors;
 7                 IServiceCollection serviceCollection = BuildCommonServices(out hostingStartupErrors);
 8                 IServiceCollection serviceCollection2 = serviceCollection.Clone();
 9                 IServiceProvider hostingServiceProvider = _003CBuild_003Eg__GetProviderFromFactory_007C13_0(serviceCollection);
10                 if (!_options.SuppressStatusMessages)
11                 {
12                     if (Environment.GetEnvironmentVariable("Hosting:Environment") != null)
13                     {
14                         Console.WriteLine("The environment variable ‘Hosting:Environment‘ is obsolete and has been replaced with ‘ASPNETCORE_ENVIRONMENT‘");
15                     }
16                     if (Environment.GetEnvironmentVariable("ASPNET_ENV") != null)
17                     {
18                         Console.WriteLine("The environment variable ‘ASPNET_ENV‘ is obsolete and has been replaced with ‘ASPNETCORE_ENVIRONMENT‘");
19                     }
20                     if (Environment.GetEnvironmentVariable("ASPNETCORE_SERVER.URLS") != null)
21                     {
22                         Console.WriteLine("The environment variable ‘ASPNETCORE_SERVER.URLS‘ is obsolete and has been replaced with ‘ASPNETCORE_URLS‘");
23                     }
24                 }
25                 AddApplicationServices(serviceCollection2, hostingServiceProvider);
26                 WebHost webHost = new WebHost(serviceCollection2, hostingServiceProvider, _options, _config, hostingStartupErrors);
27                 try
28                 {
29                     webHost.Initialize();
30                     ILogger<WebHost> requiredService = webHost.Services.GetRequiredService<ILogger<WebHost>>();
31                     foreach (IGrouping<string, string> item in from g in _options.GetFinalHostingStartupAssemblies().GroupBy((string a) => a, StringComparer.OrdinalIgnoreCase)
32                                                                where g.Count() > 1
33                                                                select g)
34                     {
35                         requiredService.LogWarning($"The assembly {item} was specified multiple times. Hosting startup assemblies should only be specified once.");
36                     }
37                     return webHost;
38                 }
39                 catch
40                 {
41                     webHost.Dispose();
42                     throw;
43                 }
44             }
45             throw new InvalidOperationException(Resources.WebHostBuilder_SingleInstance);
46         }

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

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

 1  private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
 2         {
 3             hostingStartupErrors = null;
 4             _options = new WebHostOptions(_config, Assembly.GetEntryAssembly()?.GetName().Name);
 5             if (!_options.PreventHostingStartup)
 6             {
 7                 List<Exception> list = new List<Exception>();
 8                 foreach (string item in _options.GetFinalHostingStartupAssemblies().Distinct(StringComparer.OrdinalIgnoreCase))
 9                 {
10                     try
11                     {
12                         foreach (HostingStartupAttribute customAttribute in Assembly.Load(new AssemblyName(item)).GetCustomAttributes<HostingStartupAttribute>())
13                         {
14                             ((IHostingStartup)Activator.CreateInstance(customAttribute.HostingStartupType)).Configure(this);
15                         }
16                     }
17                     catch (Exception innerException)
18                     {
19                         list.Add(new InvalidOperationException("Startup assembly " + item + " failed to execute. See the inner exception for more details.", innerException));
20                     }
21                 }
22                 if (list.Count > 0)
23                 {
24                     hostingStartupErrors = new AggregateException(list);
25                 }
26             }
27             string contentRootPath = ResolveContentRootPath(_options.ContentRootPath, AppContext.BaseDirectory);
28             _hostingEnvironment.Initialize(contentRootPath, _options);
29             _context.HostingEnvironment = _hostingEnvironment;
30             ServiceCollection serviceCollection = new ServiceCollection();
31             serviceCollection.AddSingleton(_options);
32             ((IServiceCollection)serviceCollection).AddSingleton((IHostingEnvironment)_hostingEnvironment);
33             ((IServiceCollection)serviceCollection).AddSingleton((Microsoft.Extensions.Hosting.IHostingEnvironment)_hostingEnvironment);
34             serviceCollection.AddSingleton(_context);
35             IConfigurationBuilder configurationBuilder = new ConfigurationBuilder().SetBasePath(_hostingEnvironment.ContentRootPath).AddConfiguration(_config);
36             foreach (Action<WebHostBuilderContext, IConfigurationBuilder> configureAppConfigurationBuilderDelegate in _configureAppConfigurationBuilderDelegates)
37             {
38                 configureAppConfigurationBuilderDelegate(_context, configurationBuilder);
39             }
40             IConfigurationRoot configurationRoot = configurationBuilder.Build();
41             ((IServiceCollection)serviceCollection).AddSingleton((IConfiguration)configurationRoot);
42             _context.Configuration = configurationRoot;
43             DiagnosticListener implementationInstance = new DiagnosticListener("Microsoft.AspNetCore");
44             serviceCollection.AddSingleton(implementationInstance);
45             ((IServiceCollection)serviceCollection).AddSingleton((DiagnosticSource)implementationInstance);
46             serviceCollection.AddTransient<IApplicationBuilderFactory, ApplicationBuilderFactory>();
47             serviceCollection.AddTransient<IHttpContextFactory, HttpContextFactory>();
48             serviceCollection.AddScoped<IMiddlewareFactory, MiddlewareFactory>();
49             serviceCollection.AddOptions();
50             serviceCollection.AddLogging();
51             serviceCollection.AddTransient<IStartupFilter, AutoRequestServicesStartupFilter>();
52             serviceCollection.AddTransient<IServiceProviderFactory<IServiceCollection>, DefaultServiceProviderFactory>();
53             serviceCollection.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
54             if (!string.IsNullOrEmpty(_options.StartupAssembly))
55             {
56                 try
57                 {
58                     Type startupType = StartupLoader.FindStartupType(_options.StartupAssembly, _hostingEnvironment.EnvironmentName);
59                     if (IntrospectionExtensions.GetTypeInfo(typeof(IStartup)).IsAssignableFrom(startupType.GetTypeInfo()))
60                     {
61                         serviceCollection.AddSingleton(typeof(IStartup), startupType);
62                     }
63                     else
64                     {
65                         serviceCollection.AddSingleton(typeof(IStartup), delegate (IServiceProvider sp)
66                         {
67                             IHostingEnvironment requiredService = sp.GetRequiredService<IHostingEnvironment>();
68                             return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, requiredService.EnvironmentName));
69                         });
70                     }
71                 }
72                 catch (Exception source)
73                 {
74                     ExceptionDispatchInfo capture = ExceptionDispatchInfo.Capture(source);
75                     ((IServiceCollection)serviceCollection).AddSingleton((Func<IServiceProvider, IStartup>)delegate
76                     {
77                         capture.Throw();
78                         return null;
79                     });
80                 }
81             }
82             foreach (Action<WebHostBuilderContext, IServiceCollection> configureServicesDelegate in _configureServicesDelegates)
83             {
84                 configureServicesDelegate(_context, serviceCollection);
85             }
86             return serviceCollection;
87         }

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

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

 1 public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType)
 2         {
 3             string name = startupType.GetTypeInfo().Assembly.GetName().Name;
 4             return hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, name).ConfigureServices(delegate (IServiceCollection services)
 5             {
 6                 if (IntrospectionExtensions.GetTypeInfo(typeof(IStartup)).IsAssignableFrom(startupType.GetTypeInfo()))
 7                 {
 8                     services.AddSingleton(typeof(IStartup), startupType);
 9                 }
10                 else
11                 {
12                     services.AddSingleton(typeof(IStartup), delegate (IServiceProvider sp)
13                     {
14                         IHostingEnvironment requiredService = sp.GetRequiredService<IHostingEnvironment>();
15                         return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, requiredService.EnvironmentName));
16                     });
17                 }
18             });
19         }

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

请看代码:

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

原文地址:https://www.cnblogs.com/lvshunbin/p/11072531.html

时间: 2024-11-12 21:42:07

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

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

前面三章已经把MVC启动过程以及源代码做了讲解,本章开始正式MVC,mvc全称叫model view controller,也就是把表现层又细分三层,官网的图片描述: 默认创建了一个.net core web 项目,把Startup类中的代码改成下面这样 public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Confi

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

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

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

asp.net core MVC 过滤器会在请求管道的各个阶段触发.同一阶段又可以注册多个范围的过滤器,例如Global范围,controller范围等.以ActionFilter为例,我们来看看过滤器的触发顺序. 过滤器可注册范围 全局:将作用于所有请求的action controller:将作用于这个controller下的所有action action:作用于单个action 定义过滤器 全局 public class GlobalActionFilter : IAsyncActionFi

ASP.NET Core - ASP.NET Core MVC 的功能划分

概述 大型 Web 应用比小型 Web 应用需要更好的组织.在大型应用中,ASP.NET MVC(和 Core MVC)所用的默认组织结构开始成为你的负累.你可以使用两种简单的技术来更新组织方法并及时跟进不断增长的应用程序. Model-View-Controller (MVC) 模式相当成熟,即使在 Microsoft ASP.NET 空间中亦是如此.第一版 ASP.NET MVC 在 2009 年推出,并且在今年夏初全面启动了 ASP.NET Core MVC 平台.至今,随着 ASP.NE

ASP.NET Core 入门教程 7、ASP.NET Core MVC 分部视图入门

原文:ASP.NET Core 入门教程 7.ASP.NET Core MVC 分部视图入门 一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)分部视图简介 ASP.NET Core MVC (Razor)分部视图基础教程 ASP.NET Core MVC (Razor)强类型分部视图教程 2.本教程环境信息 软件/环境 说明 操作系统 Windows 10 SDK 2.1.401 ASP.NET Core 2.1.3 IDE Visual Studio Code 1

ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门

原文:ASP.NET Core 入门教程 5.ASP.NET Core MVC 视图传值入门 一.前言 1.本教程主要内容 ASP.NET Core MVC 视图引擎(Razor)简介 ASP.NET Core MVC 视图(Razor)ViewData使用示例 ASP.NET Core MVC 视图(Razor)ViewBag使用示例 ASP.NET Core NVC 视图(Razor)强类型传值(ViewModel)页示例 2.本教程环境信息 软件/环境 说明 操作系统 Windows 10

Core MVC

Core MVC 配置全局路由前缀 前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Api 应用程序的时候,有没有遇到过这种场景,就是所有的接口都是以 /api 开头的,也就是我们的api 接口请求地址是像这样的: http://www.example.com/api/order/333 或者是这样的需求 http://www.example.com

ASP.NET Core MVC 在linux上的创建及发布

前言 ASP.NET core转眼都发布半月多了,社区最近也是非常活跃,虽然最近从事python工作,但也一直对.NET念念不忘,看过了园区大神们搭建的Asp.net core项目之后,自己也是跃跃欲试,准备搞一下ASP.NET Core mvc的创建和部署,于是便有了这篇文章,希望能够帮助到你. 环境准备 这是我的开发环境,使用的nginx是nginx 1.6.3 直接yum install,然后需要安装dotnet环境,可以参照官网教程https://www.microsoft.com/ne

ASP.NET Core MVC之Serilog日志处理,你了解多少?

前言 本节我们来看看ASP.NET Core MVC中比较常用的功能,对于导入和导出目前仍在探索中,项目需要自定义列合并,所以事先探索了如何在ASP.NET Core MVC进行导入.导出,更高级的内容还需等我学习再给出. EntityFramework Core 在学习ASP.NET Core MVC之前我们来看看在EF Core中如何更新对象指定属性,这个问题之前我们已经探讨过,但是还是存在一点问题,请往下看. public void Update(T entity, params Expr