解读ASP.NET 5 & MVC6系列教程(4):核心技术与环境配置
asp.net 5是下一代的asp.net,该版本进行了全部重写以适用于跨平台,新新版本中,微软引入了如下工具与命令:dnvm、dnx、dnu。
dnvm(.net version manager):由于要实现跨平台的目录,微软提供了dnvm功能,dnvm是asp.net最底层的内容,他是一组powershell脚本,用于启动指定版本的asp.net运行环境,并且可以在同一台机器的同一时间点上通过使用nuget工具来管理各种版本的asp.net运行环境(dnx),以及进行相应的升级操作。
dnx(.net execution environment):dnx是asp.net程序的运行环境,用于启动并运行asp.net程序。该运行环境包括了编译系统、sdk工具集、native clr宿主环境。可以使用dnvm管理各种版本的dnx,如dnvm list
命令可以列出所有可用的dnx环境,而dnvm install 0.1-alpha-build-0446
则可以将指定版本的dnx安装到.dnx文件夹,你可以在%userprofile%\.dnx\runtimes
目录下找到已安装所有版本的dnx。不同的操作系统有不同的dnx版本。
dnx.exe:dnx.exe是用于启动自宿主环境(self-hosting)的命令行工具,在使用命令行代码进行自宿主环境启动程序时,dnx负责查找并调用clr native host,dnx命令是整个运行环境的入口点,你可以使用dnx run
来启动程序。
dnu(dnx utility):是一个命令行的包管理器,包含在dnx内,所以只要安装了dnx,就可以使用dnu命令, 其可以用于恢复程序包、安装程序包、部署程序包等等,比如把project.json里自定义的程序集自动下载下来进行使用。
dnx架构及运行原理
dnx是asp.net程序运行的核心,其遵循如下两个准则:
dnx应该是自包含的,dnx在解析完应用程序依赖树以后才能知道要使用哪个core clr包,所以在得到解析树之前,dnx是无法加载任何clr的,但roslyn编译器除外。依赖注入(dependency injection,简称di)贯穿着整个系统栈,di是dnx的一个核心部分,所有dnx上的类库都构建在di之上。
dnx执行环境的分层架构如下:
layer 0:native process
该层的功能非常简单,主要就是用于查找并调用layer 1
里的clr native host
,并将系统相关的参数传递给native host
,以便后续使用。目前windows下使用dnx.exe
来处理这个事情,而iis也提供了一个中介(网站bin目录下提供一个aspnet.loader.dll
)可以将请求转发给native host
;而linux和mac则通过其相应版本的dnx来支持这项功能。
dnx用法:
dnx.exe --lib {paths} --appbase {path} [programname]
--lib {paths}:程序集dll的保存地址(一般是引用的第三方程序集和项目预编译程序集),该地址是layer 2层的托管代码入口点可以加载程序集的地方。
--appbase {path}:程序保存的目录,默认为%cd%。
[programname]:程序名称,该程序所在的程序集(或者是含有programe::main
的dll)保存在--lib
路径下,默认值是appbase\project.json
里的name。大多数情况下,该名称都是包含着加载链的程序宿主(microsoft.net.applicationhost
)。但是,如果你的程序包含了入口点(main方法),并被编译到--lib
目录下的话,你就可以使用该程序集的名称作为[programname]
,这种方式将完全忽略加载链并直接启动你的程序。
layer 1 : clr native host
这一层的内容依赖于你所选择呢clr版本,该层有如下两个职责:
启动clr,启动哪个clr取决于你选择的clr版本。如果是core clr
,该层会加载coreclr.dll
,配置并启动运行环境,然后创建应用程序域(appdomain
),以便运行所有的托管代码。调用托管代码的入口点(layer 2
),一旦native host
的入口点返回了该线程,就会把clr的线程清理干净并关闭,比如,卸载应用程序域(appdomain
)并停止运行环境。
layer 2:managed entry point
layer 2层(托管代码入口)是编写托管代码的第一层,其职责如下:
创建loadercontainer
(其包含需要的iloaders
),iloader
负责根据程序集的名称来加载程序集。clr需要一个程序集的话,loadercontainer
就会使用其iloader
来解析所需要的程序集。从--lib
的路径目录下,用根iloader
来加载程序集,并解析其依赖。调用程序的主入口点。
layer 3:application host/application
如果开发人员将整个程序编译成程序集放在libpath
目录下,那该层就是你的应用程序了。使用的时候,将含有程序入口点的程序集名称作为[programname]
的参数传入即可,layer 2
层会直接调用该程序集。
不过,一般其它情况下,都会使用一个应用程序宿主(application host
)来解析程序的依赖内容并启动运行程序。microsoft.net.applicationhost
是运行环境提供的应用程序宿主,并拥有如下职责:
解析project.json
里定义的各种依赖程序集。将一个iloader
添加到loadercontainer
,以便从各种地方(如源代码、nuget、roslyn等)加载相应的程序集。调用程序集的入口点,将其作为下一个参数,传递给dnx.exe。
layer 4:application
这一层,就是开发人员开发的程序,其运行在应用程序宿主之上。
环境配置:
要对asp.net 5程序的运行环境dnx进行配置,首先需要安装并配置dnvm,不同的操作系统安装dnvm的时候不太一样,我们在这里大概讲解一下。
windows安装命令:
//需要安装powershell 3.0 @powershell -noprofile -executionpolicy unrestricted -command "iex ((new-object net.webclient).downloadstring('https://raw.githubusercontent.com/aspnet/home/master/dnvminstall.ps1'))"
linux:
curl -ssl https://raw.githubusercontent.com/aspnet/home/master/dnvminstall.sh | sh && source ~/.dnx/dnvm/dnvm.sh
mac os x:
在mac上,首先要安装mac系统本身的包管理器homebrew(http://brew.sh
),并使用brew tap aspnet/k
命令将指定到asp.net5相关的git存储库,比如执行如下命令:
brew install dnvm
该命令将会自动从ttps://www.nuget.org/api/v2
上下载最新的dnx,下载以后,如果你的系统不识别dnvm的话,你还需要再执行一下如下语句:
source dnvm.sh
上述dnvm安装以后,系统会将dnvm文件复制到c:\program files\microsoft dnx\dnvm
目录,并将c:\program files\microsoft dnx\dnvm
目录添加到环境变量中,以便全局都可以使用。注意:这里只是安装了dnvm,并没有安装任何版本的dnx,要安装dnx的话,可以通过运行dnvm或dnvm help来查找相关的命令,具体命令如下:
dnvm upgrade [-x86][-x64] [-svr50][-svrc50] [-g|-global] [-proxy <address>]
1.从feed源安装最新版的dnx
2.为已安装的dnx设置一个默认(default)别名
3.将dnx bin添加的用户path环境变量中
4.-g|-global 在全局内进行安装(其它用户也可以使用)
5.-f|-force 强制更新成最新版(即便最新版已经安装过了)
6.-proxy 访问远程服务器的时候使用特定的地址作为代理
dnvm install <semver>|<alias>|<nupkg>|latest [-x86][-x64] [-svr50][-svrc50] [-a|-alias <alias>] [-g|-global] [-f|-force]
1.| 从feed源安装指定的dnx
2.从本地文件系统安装指定的dnx
3.latest 从feed源安装最新版的dnx
4.将dnx bin添加到当前命令行的path环境变量中
5.-p|-persistent 将dnx bin添加到系统path环境变量中
6.-a|-alias 对指定安装的dnx设置别名
7.-g|-global 在全局内进行安装
8.-f|-force 强制安装指定的dnx(即便该版本已经安装过了)
dnvm use <semver>|<alias>|none [-x86][-x64] [-svr50][-svrc50] [-p|-persistent] [-g|-global]
1.| 将dnx bin添加到当前命令行的path环境变量中
2.none 将dnx bin从当前命令行的path环境变量中删除
3.-p|-persistent 将dnx bin添加到系统path环境变量中
4.-g|-global 组合使用-p将用户path修改成系统path
dnvm list //列出所有已安装的dnx版本 dnvm alias //列出所有定义了别名的dnx版本 dnvm alias <alias> // 显示定义了别名的dnx名称 dnvm alias <alias> <semver> [-x86][-x64] [-svr50][-svrc50] //给指定的dnx版本设置别名
管理程序集的dnu命令和feed源配置
通过dnu命令进行包管理的时候,通常使用如下命令:
dnu restore
:查询程序的所有依赖包,并将其全部下载到packages目录,该命令会下载整个依赖包以及这些依赖包所依赖的其它依赖包。dun install <package id>
:该install命令用于下载指定的程序包并添加到程序中。dun publish
:该命令会将你的程序打包到一个可以运行的自包含目录中。其会创建如下目录结构:
output/ output/packages outpot/appname output/commandname.cmd
1.packages
目录包含所有应用程序需要的程序包。
2.appname
目录包含所有应用程序的代码,如果引用了其它项目,则在引用的其它项目也会创建各自项目的同级目录,即生成的目录会和appname同级。
3.publish
命令,会将project.json中的commands节点中的各种命令,分别生成响应的命令行文件,如commands里的web命令,我们就可以通过dnx web
(格式:dnx <command>
)开运行它。
由于dnu在内部使用了nuget命令,进行程序包的管理,所以使用的时候要正确配置nuget的feed源,目前asp.net 5相关的包都在myget feed上,所以我们需要添加这个feed才能正常运行。这些配置信息在windows下的%appdata%\nuget\nuget.config
(或者*nix下mono使用的~/.config/nuget/nuget.config
)文件中进行管理。示例如下:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packagesources> <add key="aspnetvnext" value="https://www.myget.org/f/aspnetvnext/api/v2/" /> <add key="nuget.org" value="https://www.nuget.org/api/v2/" /> </packagesources> <disabledpackagesources /> <activepackagesource> <add key="nuget.org" value="https://www.nuget.org/api/v2/" /> </activepackagesource> </configuration>
在vs2015下,则可以直接通过tools--> options--> nuget package manager--> package sources来设置,示例如下图:
另外需要注意一下,上述feed的地址是asp.net5的每日构建版本,如果你想使用稳定的里程碑版(如1.0.0_alpha4),则需要使用如下地址https://www.myget.org/f/aspnetmaster/api/v2/
web server支持
微软在实现dnx的时候提供了几种web服务器支持,具体分别如下:
microsoft.aspnet.loader.iis (helios)
该服务器用于在iis上加载asp.net5程序,以便和iis进程集成,同时绕过了system.web
从而带来性能上的提升,可以支持windows认证、静态文件访问等功能。其原理是将iis与ndx之间做一个桥接。
microsoft.aspnet.server.weblistener (weblistener)
该服务器通过microsoft.aspnet.hosting
在iis之外加载程序、服务、work role等,它直接运行在http.sys核心驱动之上,仅消费少许性能,从中可以受益于端口共享,windows认证等功能。
microsoft.aspnet.server.kestrel (kestrel)
该服务器通过microsoft.aspnet.server.kestrel
在iis之外加载运行,其设计被用于跨平台的web服务(windows、mac、linux等等)。
参考内容
https://github.com/aspnet/home/wiki/dnx-structure
https://github.com/aspnet/home/wiki/command-line
https://github.com/aspnet/home/wiki/version-manager
https://github.com/aspnet/home/wiki/package-manager