ASP.NET 5 引入了一个新型的运行时,让我们可以现场交付模式组合式构建应用程序,而不依赖于宿主机上的.NET框架。这种新模式为我们提供了命令行工具(DNVM、DNX、DNU)用于管理我们的.net 版本,依赖的库和运行环境,我们可以不需要Visual Studio,只需要一个文本编辑器和命令行就可以开发一个应用程序。

了解.NET 版本管理器 (DNVM) 之间 ,.NET 执行环境 (DNX) 和.NET 开发实用程序 (DNU) 之间的关系是开发 ASP.NET 5的根本。在这篇文章我们将看看在CentOS安装并使用 DNVM,DNX 和 DNU ,从命令行和文本编辑器开发一个简单应用程序,如果你使用docker,这些命令和docker还真是很像。

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 1.0.0-beta4则可以将指定版本的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程序运行的核心,其遵循如下两个准则:

  1. DNX应该是自包含的,DNX在解析完应用程序依赖树以后才能知道要使用哪个Core CLR包,所以在得到解析树之前,DNX是无法加载任何CLR的,但Roslyn编译器除外。
  2. 依赖注入(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版本,该层有如下两个职责:

  1. 启动CLR,启动哪个CLR取决于你选择的CLR版本。如果是Core CLR,该层会加载coreclr.dll,配置并启动运行环境,然后创建应用程序域(AppDomain),以便运行所有的托管代码。
  2. 调用托管代码的入口点(Layer 2),一旦Native Host的入口点返回了该线程,就会把CLR的线程清理干净并关闭,比如,卸载应用程序域(AppDomain)并停止运行环境。

Layer 2:Managed Entry Point 

Layer 2层(托管代码入口)是编写托管代码的第一层,其职责如下:

  1. 创建LoaderContainer(其包含需要的ILoaders),ILoader负责根据程序集的名称来加载程序集。CLR需要一个程序集的话,LoaderContainer就会使用其ILoader来解析所需要的程序集。
  2. 从--lib的路径目录下,用根ILoader来加载程序集,并解析其依赖。
  3. 调用程序的主入口点。

Layer 3:Application host/Application 

如果开发人员将整个程序编译成程序集放在libpath目录下,那该层就是你的应用程序了。使用的时候,将含有程序入口点的程序集名称作为[ProgramName]的参数传入即可,Layer 2层会直接调用该程序集。

不过,一般其它情况下,都会使用一个应用程序宿主(Application host)来解析程序的依赖内容并启动运行程序。Microsoft.Net.ApplicationHost是运行环境提供的应用程序宿主,并拥有如下职责:

  1. 解析project.json里定义的各种依赖程序集。
  2. 将一个ILoader添加到LoaderContainer,以便从各种地方(如源代码、NuGet、Roslyn等)加载相应的程序集。
  3. 调用程序集的入口点,将其作为下一个参数,传递给DNX.exe。

Layer 4:Application 

这一层,就是开发人员开发的程序,其运行在应用程序宿主之上。

环境配置:

要对ASP.NET 5程序的运行环境DNX进行配置,首先需要安装并配置DNVM,CentOS等Linux系统上需要先安装Mono,可以参照文章CentOS 7 上部署Mono 4 和Jexus 5.6。然后运行下面命令

curl -sSL https://raw.githubusercontent.com/aspnet/Home/master/dnvminstall.sh | sh && source~/.dnx/dnvm/dnvm.sh

[root@Mono ~]# curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh

Downloading dnvm as script to '/root/.dnx/dnvm'

Appending source string to /root/.bash_profile

Type 'source /root/.dnx/dnvm/dnvm.sh' to start using dnvm

运行命令dnvm:

上述DNVM安装以后,系统会将dnvm文件复制到/root/.dnvm目录,并将/root/.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目录,该命令会下载整个依赖包以及这些依赖包所依赖的其它依赖包。
dnu install <package id>:该install命令用于下载指定的程序包并添加到程序中。
dnu publish:该命令会将你的程序打包到一个可以运行的自包含目录中。其会创建如下目录结构:

output/

output/packages

outpot/appName

output/commandName.cmd

packages目录包含所有应用程序需要的程序包。

appName目录包含所有应用程序的代码,如果引用了其它项目,则在引用的其它项目也会创建各自项目的同级目录,即生成的目录会和AppName同级。

publish命令,会将project.json中的commands节点中的各种命令,分别生成响应的命令行文件,如commands里的web命令,我们就可以通过dnx web(格式:dnx <command>)开运行它。

由于dnu在内部使用了Nuget命令,进行程序包的管理,所以使用的时候要正确配置Nuget的feed源,目前ASP.NET 5相关的包都在myget feed上,所以我们需要添加这个feed才能正常运行。这些配置信息在*nix下Mono使用的~/.config/NuGet/NuGet.config文件中进行管理,示例如下:

从命令行开始构建一个控制台程序

我们使用vim 和dnx/dnu命令行构建一个简单的程序,创建一个目录dnx_demo, 在目录下创建一个project.json 文件,包含下面内容:

{

"version": "1.0.0-*",

"description": "geffzhang demo project",

"commands": {

"runme": "dnx_demo"

},

"frameworks": {

"dnx451": { },

"dnxcore50": {

"dependencies": {

"System.Console": "4.0.0-beta-22816",

"Microsoft.CSharp": "4.0.0-beta-22816"

}

}

}

}

上面我们定义了一个命令"runme",它指向的是工程名称:dnx_demo。我们可以通过命令行使用dnx运行我们的项目,我们的项目指向传统的.NET Framework (dnx451) 和 .NET Core (dnxcore50),所以我们可以用dnx和.net fx运行。

然后在创建一个Program.cs文件,内容如下:

using System;

namespace dnx_demo

{

public class Program

{

public void Main(string[] args)

{

Console.WriteLine("No Visual Studio Here!!");

Console.Read();

}

}

}

保存后,我们先运行命令dnu restore,将我们依赖的程序包下载到package目录。

目前我们运行的程序还仅仅是一个非常简单的控制台程序,还没有包括EF, SignalR, Identity等复杂组件,但从整个部署过程中,我们可以感觉到其实差距已经很小. 首先运行和部署环境DNVM和dnu, dnx命令和VS 2015的环境是一致的,而且组件包都是从Nuget上获取,这和标准的Windows开发环境并没有太大区别。

参考内容:

解读ASP.NET 5 & MVC6系列(4):核心技术与环境配置

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

在Linux和Mac OS X系统上运行.NET

http://www.codeproject.com/Articles/1005145/DNVM-DNX-and-DNU-Understanding-the-ASP-NET-Runtime

转载于:https://www.cnblogs.com/chenweixuan/p/5168668.html

理解ASP.NET 5运行时命令:DNVM, DNX, 和DNU相关推荐

  1. java运行提示runtime,Java 执行运行时命令 Runtime

    package cn.com.cloud.utils; import java.io.BufferedReader; import java.io.IOException; import java.i ...

  2. ASP.NET HTTP运行时组成详解(转贴)

    作者:unknown 更新时间: 2005-03-17     简介 不管使用哪种底层平台,可靠性和性能都是对所有 Web 应用程序的主要要求,尽管从某种意义上讲,这两个要求是相互矛盾的.例如,要构建 ...

  3. 深入理解JVM底层原理——运行时数据区

    运行时数据区概述和线程 1.运行时数据区概述 !     内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了Java在运行过程中内存申请 ...

  4. linux运行时命令找不到,linux - 在运行Bash脚本时找不到命令,但是在直接运行命令时有效 - 堆栈内存溢出...

    我一直在使用letencrypt为我的网站生成SSL证书,更具体地说是letencrypt_webfaction. 当我在项目中运行此命令时,它可以工作 letsencrypt_webfaction ...

  5. 谷歌黑科技:gVisor轻量级容器运行时沙箱

    2019独角兽企业重金招聘Python工程师标准>>> 谷歌发布了一种新型沙箱gVisor,可以用于为资源占用较少.不需要运行完整VM的容器提供安全隔离.gVisor的核心是一个使用 ...

  6. JVM00_面试官对类加载器子系统、运行时数据区、内存分布、执行引擎的灵虚拷问,你能坚持到第几问?

    因为热爱所以坚持,因为热爱所以等待.熬过漫长无戏可演的日子,终于换来了人生的春天.他逐渐被人熟知,被人喜爱 三年前,在苏州园区某个国企面试,第一道题目便是:JVM是什么吗?然后就是拿着笔试题目被面试官 ...

  7. 1.Containerd容器运行时初识与尝试

    0x00 前言简述 1.基础介绍 2.专业术语 3.架构简述 0x01 安装配置 1.Ubuntu安装Containerd.io流程 0x02 简单使用 1.镜像拉取与运行 2.创建和使用网络 3.与 ...

  8. 常量池(运行时常量池 静态常量池)

    深入浅出java常量池 理论 jvm虚拟内存分布:      程序计数器是jvm执行程序的流水线,存放一些跳转指令.      本地方法栈是jvm调用操作系统方法所使用的栈.      虚拟机栈是jv ...

  9. 从.Net类库代码来看Asp.net运行时(转自酷网动力)

    写在前面的话:网上讲Asp.net运行模式的好文章已经很多了,笔者本不用多此一举,另成一文.但从笔者自己的学习经验看,如果学到的这些知识不能对应 到类库中的源代码,印象总归不够深刻,大有隔靴搔痒之感. ...

最新文章

  1. 分摊的意思_会计分摊是什么意思
  2. Android Studio安装踩坑
  3. 【联盛德W806上手笔记】二、GPIO
  4. MySQL数据库在众多表中对表名的查询及预处理存储过程(变量做表名)
  5. echarts固定柱子宽度(barWidth)
  6. 大数据如何应用在生活中
  7. Futter基础第15篇: 实现类似闲鱼App底部导航凸起按钮
  8. Java出现The import javax.servlet cannot be resolved 的解决方法
  9. CMU 15-213 Introduction to Computer Systems学习笔记(16) Virtual Memory: Concepts
  10. linux监控程序-程序自动重启方法(转)
  11. Android计算器代码分析
  12. 【预测模型】趋势移动平均法预测发电量
  13. MATLAB输出白色背景图片
  14. NTC热敏电阻的主要技术参数
  15. 9.1 一切让代码行数说话——《逆袭大学》连载
  16. sd卡怎么格式化?5个步骤轻松教会你
  17. ElasticSearch 倒排索引(Inverted Index)| 什么是倒排索引?
  18. UnityShader快速上手指南(四)
  19. 我的世界手机版服务器文件,《我的世界手机版》服务器配置文件详解教程攻略...
  20. lise什么意思中文翻译_法语助手|法汉-汉法词典 lise是什么意思_lise的中文解释和发音_lise的翻译_lise怎么读...

热门文章

  1. python 如果你的年龄大于18_5分钟学会Python的if条件判断语句
  2. 魔兽世界灵魂兽刷新和服务器维护,魔兽世界灵魂兽 刷新地点整理及外观点评...
  3. bottom sheets_使用Sheetson建立由Google Sheets支持的免费电子邮件列表
  4. JavaScript知识点整理(十六)- PC端网页特效 - 案例练习
  5. 手机App开发行业前景怎么样?
  6. python随机函数random、画、星轨_如何使用 NVIDIA StyleGAN 生成自己的动漫(老婆)头像...
  7. 芯片附近为什么都放 0.1uF 电容 ?
  8. vue简单的金额计算
  9. Win11 解决wifi连接出现的无法连接该网络的问题
  10. Hadoop的序列化和反序列化