.NET KRuntime 程序加载流程(coreCLR)
(本人纯属个人见解)
STEP 1
K.cmd paramlist
paramlist={
-AppBase
-Lib
Command
}
if Command like k-*
Call k-*.cmd
else
Let paramlist= Microsoft.Framework.ApplicationHost + paramlist
Call KLR.exe paramlist
endif
总结:准备参数,并启动KLR进程,paramlist在每次跨模块调用时都会传递
STEP 2
KLR.exe(native)
if CORECLR
Call CallApplicationMain[klr.core45.dll]
else
Call CallApplicationMain[klr.net45.dll]
endif
总结:根据不同的CLR,创建不同的运行环境
STEP 3
klr.core45.dll(native)
1.加载coreclr.dll(native)
2.加载并启动CLRRuntimeHost
Let CLRRuntimeHost = Call GetCLRRuntimeHost[coreclr.dll]
Call CLRRuntimeHost.Start
3.创建AppDomain
Call CLRRuntimeHost.CreateAppDomainWithManager
4.Call DomainManager.Execute[klr.core45.managed.dll]
总结:创建.net必须的可以执行托管代码的运行时环境
STEP 4
klr.core45.managed(managed)
Call RuntimeBootstrapper.Execute[klr.hosting.shared.dll(managed)]
Call Bootstrapper.Main[klr.host.dll]
提取 paramlist第一个参数( Microsoft.Framework.ApplicationHost )
Let paramlist= paramlist - paramlist[0]
Call Program.Main[Microsoft.Framework.ApplicationHost]
总结:根据参数,创建一个托管代码程序的宿主,宿主就是负责以什么规则去加载和运行托管程序,这里Microsoft.Framework.ApplicationHost是一个参数,可以自己实现一个,也就是说一个程序的物理结构是啥样,你自己决定了。
STEP 5
Microsoft.Framework.ApplicationHost(managed)
1.创建DefaultHost
1.读取project.json配置文件
2.解析项目依赖项(包括Reference Assemblies、GAC Assemblies、NuGet Packages)并加载
2.确定程序入口ApplicationName
{ApplicationName}默认是应用程序的目录(比如ConsoleApp1)
{programArgs}默认是paramlist剩下的数据
提取paramlist.command:
比如run或者web
如果project.json的commands项中存在此命令,则{ApplicationName}等于其值的第一个 参数,{programArgs}就是剩下的值
下面是个配置command demo
"web": "Microsoft.AspNet.Hosting
--server Microsoft.AspNet.Server.WebListener
--server.urls http://localhost:5000"
3.加载 {ApplicationName}.dll并调用Program.Main(programArgs)
如果是ConsoleApp,调用Program.Main,程序开始
如果是Web App,则调用Program.Main[Microsoft.AspNet.Hosting]
总结:.Net vNext程序的必须配置信息都存储在project.json中,这里就是围绕着这些配置信息从各种程序源去加载依赖项;
还有程序入口你可以指定,通过project.json配置,只要求你的程序包括Program.Main程序入口,也就是ConsoleApp必须包括Program.Main;
Console App与Web App的加载区别就是ConsoleApp自己提供了Program.Main,而Web App的入口是Microsoft.AspNet.Hosting的Program.Main,然后它再来负责运行的web.