欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-08-12 10:09:23
前一篇提到WebHost.CreateDefaultBuilder(args)方法创建了WebHostBuilder实例,WebHostBuilder实例有三个主要功能 1、构建了IConfiguration实例和基础环境配置,2、构建了IServiceCollection服务,也就是依赖注入的容器 ......

前一篇提到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         }

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

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

调用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容器管理,具体请看下图

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

这里讲清楚之后,我们直接进入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方法

请看代码:

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

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