Unstoppable curiosity: How ASP. NET 5 implements cross-platform implementation through XRE
. NET programmers also have their own happiness ,. NET cross-platform is a kind of happiness ,. NET open source is also a kind of happiness, and more happy is that the open source. NET. NET step by step to cross-platform, so happiness is a process.
In the process of. NET cross-platform, ASP. NET is clearly at the forefront. By exploring how ASP. NET 5 implements cross-platform, you can satisfy your curiosity.
There are two ways to experience ASP. NET 5 cross-platform:
1) on Mac, git checks out the source code of XRE, whose predecessor is KRuntime), and then runs sh build. sh to generate the entire XRE project.
2) write a simple ASP. NET project under Mac and run it with k kestrel. For details, see do not write 1 line of code, and try ASP. NET 5 on Mac.
This blog post will start with the k Command to explore ASP. NET 5 cross-platform.
Run the following command according to the commands configuration in project. json ):
k "Microsoft.AspNet.Hosting --server kestrel --server.urls http://localhost:8002"
Microsoft. aspNet. hosting is. NET console program implemented by the OWIN Host source code), kestrel is a libuv-based. net owin Server is also a Web Server, source code), kestel is by Microsoft. aspNet. hosting is loaded.
Since Microsoft. AspNet. Hosting is a managed program, it cannot run directly on its own. The precondition for running a. NET program is that the CLR is running, but the CLR itself cannot run itself. the precondition for running the CLR is that a host Program loads it.
If you have used Mono on a Mac, you will know how to run one. the NET program requires the mono command. The mono command is used to create a process, load Mono Runtime (Mono CLR), and then run Mono Runtime.. NET program.
In ASP. NET 5, the mono command is not directly used, but the k Command. Since KRuntime is renamed as XRE, the k Command will also be replaced by the dotnet command.
On non-Windows platforms, the k Command corresponds to k. sh. Now change to XRE, that is, the donet command corresponds to dotnet. sh. Therefore, the ASP. NET 5 cross-platform secret is hidden in dotnet. sh.
In the XRE project, click scripts/dotnet. sh:
#...if [ -f "$DIR/mono" ]; then exec "$DIR/mono" $MONO_OPTIONS "$DIR/dotnet.mono.managed.dll" "$@"else exec mono $MONO_OPTIONS "$DIR/dotnet.mono.managed.dll" "$@"fi
No suspense. mono is still used. But with mono, how does one load. NET Core CLR? Does it still use Mono Runtime?
With this question, let's look at what dotnet. mono. managed. dll has done.
Dotnet. mono. managed. the dll implementation code is a simple C # console program in the XRE project. It does two things: 1) analyze the command line parameters; 2) Call RuntimeBootstrapper. execute ():
public class EntryPoint{ public static int Main(string[] arguments) { //... arguments = ExpandCommandLineArguments(arguments); //... return RuntimeBootstrapper.Execute(arguments); }}
Continue to [dotnet. hosting. RuntimeBootstrapper]. [RuntimeBootstrapper. Execute ()] calls [RuntimeBootstrapper. ExecuteAsync ()].
However, the managed [RuntimeBootstrapper. ExecuteAsync ()] turns around and executes an unmanaged dotnet command, a C ++ program implemented by dotnet. cpp ).
Mono commands (unmanaged)-> Mono Runtime-> dotnet. mono. managed (managed)-> RuntimeBootstrapper (managed)-> dotnet command (unmanaged), ASP. NET 5 XRE code is really 18 bend.
The original main character was hidden after the 18 th bend.
Dotnet. cpp loads the unmanaged dotnet. coreclr. dll:
LPCWSTR pwzHostModuleName = L"dotnet.coreclr.dll";
m_hHostModule = ::LoadLibraryExW(pwzHostModuleName, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
pfnCallApplicationMain = (FnCallApplicationMain)::GetProcAddress(m_hHostModule, pszCallApplicationMainName);
Dotnet. coreclr. dll is implemented by the C ++ program dotnet. coreclr. cpp in XRE, and coreclr. dll is loaded by dotnet. coreclr. cpp:
hCoreCLRModule = ::LoadLibraryExW(L"coreclr.dll", NULL, 0);
Dotnet. coreclr. cpp is the main character of CLR loading.
This is not a question. Is that true? Only one C ++ program can load CLR and execute. NET programs. Why should we install a large. NET Framework on Windows?
Yes! An unmanaged host Program + CLR can run the. NET program. If you don't believe it, read this article to shock you: Hosting. NET Core Clr in your own process.
The CLR is loaded for execution. NET assembly, and the Assembly to be executed is passed by the command line parameters of the dotnet command predecessor is k Command), for example, before dotnet kestrel is k kestrel ), the corresponding assembly is Microsoft. aspNet. hosting. CLR calls Microsoft. AspNet. Hosting. Program. Main () method to start execution, and ASP. NET 5 starts to work.
Core CLR loaded, Microsoft. aspNet. after Hosting is run. in ExecuteAsync (), some dotnet. host-related Assembly note: this is not the Core CLR, but the Mono Runtime ).
//...var assembly = Assembly.Load(new AssemblyName("dotnet.host"));//...var loaderContainerType = assembly.GetType("dotnet.host.LoaderContainer");var cachedAssemblyLoaderType = assembly.GetType("dotnet.host.CachedAssemblyLoader");var pathBasedLoaderType = assembly.GetType("dotnet.host.PathBasedAssemblyLoader");//...
At this point, I wonder if you have been dizzy by the 18 turns. If you have not been dizzy, continue to look down.
At this moment, a big question mark emerges. Since the dotnet command can directly load the Core CLR, why should I use the mono command to transfer it?
I cannot explain it...
In the course of writing this blog post, a bold conjecture suddenly emerged --
After Core CLR is loaded and Microsoft. AspNet. Hosting is executed, why do I need to use Mono Runtime to load some dotnet. host-related assemblies? Why not use Core CLR to load data directly? This can only be explained for one reason, dotnet. the host depends on some assembly in. NET Framework, but in. NET Core Framework is not implemented yet, while Mono is. NET Framework is a cross-platform implementation, which also corresponds to Mono. The complete. NET Core Frameworkgithub.com/dotnet/corefx is still under development. Before it comes out, Microsoft can only use Mono. This is also the price that ASP. NET has to pay for cross-platform development. With the completion of the. NET Core Framework and the improvement of XRE, it is expected that ASP. NET cross-platform development will be separated from Mono.
Of course, this is just a conjecture. If you know the truth, you are welcome to unveil it.