通过几个Hello World感受.NET Core全新的开发体验

2016年6月27日,这是一个特殊的日子,微软全新的.NET开发平台.NET Core的RTM版本正式发布。我个人将.NET Core的核心特性归结为三点,它们的首字母组成一个非常好记的简称——COM,分别代表的含义Cross-Platform、Open-Source和Modularization。开发.NET Core应用的方式与之前具有非常大的变化,对于那些尚未体验过.NET Core的朋友,我希望通过本篇文章创建的这j几个Hello World应用可以很容易地带你们快速入门。

首先我们会介绍如何构建.NET Core应用的开发环境。在这之后,我们会利用dotnet new命令行创建一个控制台类型的Hello World应用,这个简单的应用时后续几个Hello World应用的雏形,后者都是通过它改变而成。我们做的第一个改变是将它变成一个ASP.NET Core应用,并采用Self-Host的方式将它寄宿于这个控制台应用中。这个ASP.NET Core应用被进一步改造成一个ASP.NET Core MVC应用,我们会自行定义Controller和View已经路由。

目录
一、构建开发环境
二、执行dotnet new命令创建一个控制台应用
三、将应用修改成一个ASP.NET Core应用
四、自行指定监听地址
五、将应用修改成一个ASP.NET Core MVC应用
六、添加View

 

一、构建开发环境

根据自身的操作系统类型安装和运行环境.NET Core SDK、IDE和相关的工具

二、执行dotnet new命令创建一个控制台应用

我们直接启动命令行工具,为创建的Hello World应用创建一个根目录(%USERPROFILE% projects/helloworld)。在将该目录设置为当前目录后,我们按照如下的方式执行“dotnet new”命令。源代码下载:netcore.helloworld1

image

dotnet new命令会为我们创建一个由如下两个文件组成的控制台应用。

image

作为程序入口的Main方法定义在Program.cs文件中,如下所示的代码片段体现了该文件的整体定义,我们可以看到Main方法仅仅是在控制台上打印出“Hello World”字样而已。

   1: using System;
   2: namespace ConsoleApplication
   3: {
   4:     public class Program
   5:     {
   6:         static void Main(string[] args)
   7:         {
   8:             Console.WriteLine("Hello World!");
   9:         }
  10:     }
  11: }

我们创建的控制台项目直接映射为一个目录,项目自身的设置定义在project.json这个文件中,该文件的整体定义反应在如下所示的代码片段中。整个文件由四个节点组成,其中version和buildOptions用来定义目标项目的版本和编译选项。dependencies在用来存放针对NuGet包的依赖。我们创建的项目可以针对一个或者多个Framework(比如我们希望创建的可以同时在.NET Framework和.NET Core上运行),支持的Framework定义在frameworks节点下。如果添加了多个Framework,并不是说最终生成的应用可以同时在这些Framework中运行,而是说源文件在编译的时候会针对这些Framework生成对应的程序集。

2: "version": "1.0.0-*",
"debugType": "portable",1)">   5:     "emitEntryPoint": true
   9:     "netcoreapp1.0": {
  11:         "Microsoft.NETCore.App": {
  12:           "type": "platform",1)'>  13:           "1.0.0"
  14:         }
  15:       },1)'>  16:       "imports": "dnxcore50"
  17:     }
  18:   }
  19: }

对于传统的.NET项目来说,如果我们需要调用某个API,需要添加所在程序集的引用。对于.NET Core来说,所有使用到的程序集都被打包成一个NuGet包,所以针对程序集的直接依赖转变成针对某个NuGet包的依赖。针对NuGet的依赖主要有两种类型,一种是针对所有Framework的,它们会直接定义在dependencies节点下,另一种则是针对某个具体Framework的,定义的定义为当前Framework节点下的dependencies子节点。我们定义在Project.json中的设定的NuGet包可能尚未在本地安装,我们可以执行dotnet restore命令获取并在本地安装所有需要的NuGet包。一旦完成了针对NuGet包的回复操作,我们就可以直接执行dotnet run命令来启动应用。在这期间,我们的应用实际上会经历一个编译的过程,我们也可以执行dotnet build命令对其实施编译。如下面的代码片段所示,我们分别先后执行restore、build和run三个命令,目标程序最终得以执行。

image

三、将应用修改成一个ASP.NET Core应用

接下来我们将这个控制台应用改造成一个最简单的ASP.NET Core应用。IDE的选择,我们可以使用VS 2015,也可以使用VS Code,假设我们选择前者。我们以开启项目(File->Open->Project/Solution)的方式打开project.json后,相当于开启了整个控制台项目。ASP.NET Core的核心管道定义在NuGet包“Microsoft.AspNetCore.Hosting”中,以Self-Host的方式寄宿ASP.NET Core应用还需要一个Server,我们选择的是定义在“Microsoft.AspNetCore.Server.Kestrel”这个NuGet包中的KestrelServer,所以我们第一步需要做的就是在project.json中添加针对这两个NuGet包的依赖。源代码下载:netcore.helloworld2

18: },1)"> 19: 20: }
  21:   }
  22: }

ASP.NET Core应用的寄宿依赖于一个WebHost对象,后者则通过对应的工厂WebHostBuilder创建,为此我们将针对WebHost的创建定义在作为入口点的Main方法中。如下面的代码片段所示,我们创建了一个WebHostBuilder对象,在调用其Build方法创建WebHost对象之前,我们先后调用了前者的UseKestrel和UseStartup方法。前者的目的在于注册上面提及的这个叫做KestrelServer的Server,后者则注册一个启动类型Startup。WeHost的Run方法一旦调用,意味着ASP.NET Core应用被启动。

3: using Microsoft.AspNetCore.Builder;
   5:  
   8:        9:     {
  12:             new WebHostBuilder()
  14:             .UseStartup<Startup>()
  16:             .Run();
  19: }

ASP.NET Core应用的背后是一个由Server和Middleware构成的管道,Server实现针对请求的监听、接收和响应,而注册的Middleware则负责对请求进行处理。WebHostBuilder的UseKestrel方法为管道注册了必不可少Server,Middleware的注册在实现在由UseStartup方法注册的启动类型中。如下所示的是我们注册的Startup类型的定义,我们在Configure方法中调用ApplicationBuilder的扩展方法Run注册了唯一的Middleware,它对请求的处理逻辑简单而直接——直接响应一个“Hello World”字符串。

class Startup
  12:             app.Run(context=>context.Response.WriteAsync("Hello World"));
  15:         
  17: }

我们同样按照上面的方式执行dotnet restore和dotnet run命令,ASP.NET Core应用将被启动。

image

上控制台上的输出我们可以看出,ASP.NET Core启动后会绑定到默认的地址“http://localhost:5000/”来监听请求,所以我们可以利用浏览器向这个地址发送请求,应用处理请求后会按照如下的形式响应由注册的Middleware写入的“Hello World”。

image

四、自行指定监听地址

我们在利用WebHostBuilder创建WebHost,以及利用后者启动ASP.NET Core应用的整个过程中并没有显式指定Server监听的地址,在此情况下默认的监听地址“http://localhost:5000/”会被使用。我们也可以自行指定这个监听地址,该地址可以通过调用WebHostBuilder的扩展方法UseUrls来指定。如下面的代码片段所示,我们在利用WebHostBuilder创建WebHost之前调用UseUrls方法注册了两个监听地址“http://localhost:8888/“和“http://localhost:9999/”。源代码下载:netcore.helloworld3

16: .Build()
  18:         }
  20: }

当应用再次被启动后,监听地址将发生改变,我们可以改变浏览器的目标地址来对此做验证。

image

五、将应用修改成一个ASP.NET Core MVC应用

我们继续对上面这个ASP.NET Core应用进行改造,并将其构建成一个MVC应用。建立在ASP.NET Core的所有的开发框架都是通过注册到管道中的某一个或者多个Middleware实现的。针对MVC的Middleware实现了路由、Controller的激活、Action方法的执行以及View的呈现。相关的类型通过“Microsoft.AspNetCore.Mvc”这个NuGet包承载,所以我们需要添加这个NuGet包的依赖。简单起见,我们只需要直接将project.json中添加的“Microsoft.AspNetCore.Hosting”替换成“Microsoft.AspNetCore.Mvc”即可。

using Microsoft.Extensions.DependencyInjection;
  12:             services.AddMvc();
  14:         
  17:             app.UseMvc();            
  20: }

对于一个MVC应用来说,任意一个请求都是指向定义在目标Controller的某个Action方法中,接下来我们就来定义如下一个HomeController。ASP.NET Core MVC不像之前的MVC版本要求Controller实现IController接口,它可以是一个普通一个以Controller为后缀命名的公共类型。我们在HomeController中定义的Action方法Index,该方法上应用HttpGetAttribute以特性注入的形式注册了模板为“/{name}”的路由。

3: 
   6:     class HomeController
   8:         [HttpGet("/{name}")]
  10:         {
  12:         }
  14: }

当我们按照上面的方式启动这个ASP.NET Core MVC应用后,如果我们利用浏览器访问与注册路由相匹配的目标地址(“http://localhost:9999/foobar”),可以得到如下所示的相应结果。源代码下载:netcore.helloworld4

image

六、添加View

接下来我们为上面这个MVC应用添加View。为此我们需要按照如下的方式改写HomeController。我们让它继承基类Controller,并改变Action方法Index的返回类型(IActionResult),该方法直接调用View方法返回只想默认View的ViewResult对象。再次之前,我们将传入的参数name保存在ViewBag中。

4: {
   6:     {
  10:             ViewBag.Name = name;
  14: }

接下来我们来定义Action方法Index指向的这个View,按照约定我们应该将对应的Index.cshtml文件存放在/Views/Home目录下。该View定义如下。

2: head 3: title>Hello</ 5: body>Hello,@ViewBag.Name>

由于我们使用到了Razor引擎,我们同样需要将相关的NuGet包“Microsoft.AspNetCore.Razor.Tools”按照如下的方式添加到project.json文件中。除此之外,基于View动态编译的需要,我们需要添加一个名为“preserveCompilationContext”的编译选项,并将其值设置为true。

7: },1)">"Microsoft.AspNetCore.Mvc": 10: "Microsoft.AspNetCore.Razor.Tools": {
  11:       "1.0.0-preview2-final",
  12:       "build"
  16:   },1)">  17:     18:       20:           21:             22:             23:         }
  24:       },1)'>  25:         26:     }
  27:   }
  28: }

除此之外,View的定位依赖于一个根路径,所以我们需要按照如下的方式调用WebHostBuilder的UseContentRoot方法将当前目录设置为此根目录。

4: 
   7:        8:     {
  13:             .UseStartup<Startup>()
  15:             .UseUrls(  20: }

当我们按照上面的方式启动这个ASP.NET Core MVC应用后,如果我们利用浏览器访问与注册路由相匹配的目标地址(“http://localhost:9999/foobar”),可以得到如下所示的相应结果。源代码下载:netcore.helloworld5

image

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发、订阅和处理的流程。这种实现太简单了,百十行代码就展示了一个基本工作原理。然而,要将这样的解决方案运用到实际生产环境,还有很长的路要走。今天,我们就研究一下在事件处理器中,对象生命周期的管理问题。事实上,不仅仅是在事件处理器
上文已经介绍了Identity Service的实现过程。今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关。 回顾 《Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)》 Weather API Weather
最近我为我自己的应用开发框架Apworks设计了一套案例应用程序,并以Apache 2.0开源,开源地址是:https://github.com/daxnet/apworks-examples,目的是为了让大家更为方便地学习和使用.NET Core、最新的前端开发框架Angular,以及Apwork
HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务端接口的耦合度。很多当今流行的RESTful API开发框架,包括Spring REST,也都默认支
在前面两篇文章中,我详细介绍了基本事件系统的实现,包括事件派发和订阅、通过事件处理器执行上下文来解决对象生命周期问题,以及一个基于RabbitMQ的事件总线的实现。接下来对于事件驱动型架构的讨论,就需要结合一个实际的架构案例来进行分析。在领域驱动设计的讨论范畴,CQRS架构本身就是事件驱动的,因此,
HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单、统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable)更强,并具有自描述的特点。使用了HAL的API会更容易地被第三方开源库所调用,并且使用起来也很方便
何时使用领域驱动设计?其实当你的应用程序架构设计是面向业务的时候,你已经开始使用领域驱动设计了。领域驱动设计既不是架构风格(Architecture Style),也不是架构模式(Architecture Pattern),它也不是一种软件开发方法论,所以,是否应该使用领域驱动设计,以及什么时候使用
《在ASP.NET Core中使用Apworks快速开发数据服务》一文中,我介绍了如何使用Apworks框架的数据服务来快速构建用于查询和管理数据模型的RESTful API,通过该文的介绍,你会看到,使用Apworks框架开发数据服务是何等简单快捷,提供的功能也非常多,比如对Hypermedia的
在上一讲中,我们已经完成了一个完整的案例,在这个案例中,我们可以通过Angular单页面应用(SPA)进行登录,然后通过后端的Ocelot API网关整合IdentityServer4完成身份认证。在本讲中,我们会讨论在当前这种架构的应用程序中,如何完成用户授权。 回顾 《Angular SPA基于
Keycloak是一个功能强大的开源身份和访问管理系统,提供了一整套解决方案,包括用户认证、单点登录(SSO)、身份联合、用户注册、用户管理、角色映射、多因素认证和访问控制等。它广泛应用于企业和云服务,可以简化和统一不同应用程序和服务的安全管理,支持自托管或云部署,适用于需要安全、灵活且易于扩展的用
3月7日,微软发布了Visual Studio 2017 RTM,与之一起发布的还有.NET Core Runtime 1.1.0以及.NET Core SDK 1.0.0,尽管这些并不是最新版,但也已经从preview版本升级到了正式版。所以,在安装Visual Studio 2017时如果启用了
在上文中,我介绍了如何在Ocelot中使用自定义的中间件来修改下游服务的response body。今天,我们再扩展一下设计,让我们自己设计的中间件变得更为通用,使其能够应用在不同的Route上。比如,我们可以设计一个通用的替换response body的中间件,然后将其应用在多个Route上。 O
不少关注我博客的朋友都知道我在2009年左右开发过一个名为Apworks的企业级应用程序开发框架,旨在为分布式企业系统软件开发提供面向领域驱动(DDD)的框架级别的解决方案,并对多种系统架构风格提供支持。这个框架的开发和维护我坚持了很久,一直到2015年,我都一直在不停地重构这个项目。目前这个项目在
好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名《Angular单页面应用基于Ocelot API网关与IdentityServer4ʺSP.NET Identity实现身份认证与授权》,然而如你所见,这样的名字实在是太长了。所以,我不得不缩写“单页面应用”几个字
在前面两篇文章中,我介绍了基于IdentityServer4的一个Identity Service的实现,并且实现了一个Weather API和基于Ocelot的API网关,然后实现了通过Ocelot API网关整合Identity Service做身份认证的API请求。今天,我们进入前端开发,设计
Ocelot是ASP.NET Core下的API网关的一种实现,在微服务架构领域发挥了非常重要的作用。本文不会从整个微服务架构的角度来介绍Ocelot,而是介绍一下最近在学习过程中遇到的一个问题,以及如何使用中间件(Middleware)来解决这样的问题。 问题描述 在上文中,我介绍了一种在Angu
在大数据处理和人工智能时代,数据工厂(Data Factory)无疑是一个非常重要的大数据处理平台。市面上也有成熟的相关产品,比如Azure Data Factory,不仅功能强大,而且依托微软的云计算平台Azure,为大数据处理提供了强大的计算能力,让大数据处理变得更为稳定高效。由于工作中我的项目
在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容。下面的类图描述了我们已经实现的组件及其之间的关系,貌似系统已经变得越来越复杂了。其中绿色的部分就是上文中新实现的部分,包括一个简单的Event Store,一个事件处理器执行上下文的接
在之前《在ASP.NET Core中使用Apworks快速开发数据服务》一文的评论部分,.NET大神张善友为我提了个建议,可以使用Compile As a Service的Roslyn为语法解析提供支持。在此非常感激友哥给我的建议,也让我了解了一些Roslyn的知识。使用Roslyn的一个很大的好处
很长一段时间以来,我都在思考如何在ASP.NET Core的框架下,实现一套完整的事件驱动型架构。这个问题看上去有点大,其实主要目标是为了实现一个基于ASP.NET Core的微服务,它能够非常简单地订阅来自于某个渠道的事件消息,并对接收到的消息进行处理,于此同时,它还能够向该渠道发送事件消息,以便