当前位置: 移动技术网 > IT编程>开发语言>.net > .net core mvc启动顺序以及主要部件2

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

2019年06月23日  | 移动技术网IT编程  | 我要评论

uedbet8.cc,豆包战国,泸县论坛

前一篇提到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类的过程大致就到这里了

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网