本文将对微软下一代ASP.NET框架作个归纳性介绍,方便你们进一步熟悉该框架。html
在介绍ASP.NET Core 1.0以前有必要澄清一些产品名称及版本号。ASP.NET Core1.0是微软下一代ASP.NET 框架,在这以前ASP.NET版本稳定在ASP.NET 4.6,对应的.NET Framework版本为.net 4.6.1。前端
曾经一段时间微软将下一代ASP.NET 命名为ASP.NET 5和MVC 6,在ASP.NET 5 is dead – Introducing ASP.NET Core 1.0 and .NET Core 1.0一文中,微软第一次提到ASP.NET 5将会改成ASP.NET Core1.0。git
该文还指出了.NET其余产品命名变化github
之因此有这样的改变,微软解释为:下一代的ASP.NET并非ASP.NET 4.6的简单升级,若是命名为ASP.NET 5则会给开发者一个错误的暗示,开发者会误认为这只是功能上的升级。而事实是微软首先写了一个轻量级跨平台的.NET Core,而后在该平台下从新设计了ASP.NET,新一代的ASP.NET Core 1.0有着众多新的特性,固然最重要的是实现了跨平台。web
值得注意的是从ASP.NET 5到ASP.NET Core 1.0这一命名的转变会对开发人员形成一些困惑,由于在一些ASP.NET相关的网站中,仍然能够不时地看到Asp.net 5 或者MVC 6等名称。事实上,因为ASP.NET Core 1.0正式版尚未发布,命名的改变还在进行当中,整个命名的改变过程到ASP.NET Core1.0正式发布以后才会所有结束。
于此同时也产生了一些新的概念:
DNX:.NET Execution Environment,即.NET运行时环境,在Windows,Mac和Linux下运行.NET应用程序的环境(有点目前windows环境下的.NET Framework的意思),固然这东西是跨平台的,这是跟.NET Framework最大的不一样之处。
DNVM:NX Version Manager,即DNX的版本管理工具,利用DNVM能够管理DNX的不一样版本,你能够轻松切换到不一样的DNX版本中。
.NET Core:能够理解为一个通过精简的、模块化的.NET Framework子集,目的是为了跨平台。.NET Core有一系列的类库组成,叫作"CoreFX",一个更精简的版本叫作"CoreCLR"。编程
整个.NET Core全部类库包括以前提到的ASP.NET Core都是经过Nuget来管理的。json
1、安装ASP.NET Core 1.0windows
这一过程在Windows、Mac和Linux下各不相同,微软给出了详细的安装文档,以Windows为例又分为两种方式,下载安装或经过命令行安装。浏览器
2、新建ASP.NET Core项目服务器
安装完毕后,VS2015会增长对应的模板,值得注意的是该模板目前仍旧叫作ASP.NET 5。
3、项目结构
一、project.json文件:
dependencies节点:用来管理Nuget依赖,支持智能提示,这一过程等价于在Nuget package Manager中管理依赖项。
commands节点:在DNX环境下可使用dnx [command]命令来执行一组命令,对于:
"commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" },
能够这样使用:
dnx web //这一命令将会启动KestrelHttp 服务器,KestrelHttpServer是微软基于libuv编写的跨平台web 服务器 dnx ef
二、frameworks节点:该节点定义了DNX环境
"frameworks": { "dnx451": { }, "dnxcore50": { } },
dnx451表示.NET Framework 4.5.1,dnxcore50表示.NET Core5。
该节点代表此程序能够跑在这两种DNX环境中,在代码中还能够经过下面的方式针对具体的环境编写代码。
#if DNX451 // utilize resource only available with .NET Framework #endif
4、ASP.NET Core1.0带来的新特性
一、采用新的文件系统,再也不经过工程文件(.sln和.csproj)来定义项目文件清单。
以本Demo为例,全部添加在AspnetCore.Practice文件夹下的文件都会被自动添加在项目中,举个例子:
打开AspnetCore.Practice\Controllers文件夹:在文件夹内手工添加一个文件ServiceController.cs,并添加以下测试代码:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.Mvc; namespace AspnetCore.Practice.Controllers { public class ServiceController : Controller { public IActionResult Index() { return Content("hello world"); } } }
注意,此时打开VS的项目管理器,能够看到ServiceController已经添加到了项目中。这时若在浏览器中直接输入测试代码的url,便可看到测试结果。也就是说VS在后台监视到了新文件便会自动添加在项目中并自动完成编译。
二、Startup类。
该类能够看做整个ASP.NET Core的启动入口,该类主要存在3个方法:Main函数是入口点,方法ConfigureServices用来向IOC容器中注册组建,方法Configure则用来注册Middleware。
也许你第一次见到这个类会有点不明觉厉,该类中3个方法既没有接口约束,也没有从父类继承。微软在该处采用了这样一种约定:必需要存在一个名叫Startup的类,同时该类必需要存在上面提到的3个方法,该ASP.NET项目才能顺利运行成功。
采用约定而非契约编程的缘由在于约定更加灵活。特别是在方法Configure()签名中,参数能够从容器中注入,意味着你能够定义这样的Configure方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { //... }
也能够定义这样的Configure方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory,IUserProvider userProvider) { //... }
要保证这样的灵活性对于契约编程很难作到。
即使你对约定这一事实一无所知,一些异常信息也会帮助你朝着正确的方向编写代码。好比当你将Startup类重命名为其余,例如命名为Bootstrapper,你将会获得以下的提示:
一样的道理,若是方法ConfigureServices或Configure漏写也会获得类似的提示。
该类除了采用约定,大部分代码都是在接口上实现扩展方法的风格,想进一步了解这种代码风格请阅读《再谈扩展方法,从string.IsNullOrEmpty()提及》。
三、读取Appsetting
因为已经再也不存在web.config文件,因此新的Appsetting也采起了更加通用的设计。在新建项目的时候VS已经帮咱们添加了默认的appsettings.json文件。
定义一个键值对:"hello": "Hello, world",同时在Startup类的构造函数中将appsettings.json文件添加到了ConfigurationBuilder对象中:
public Startup(IHostingEnvironment env) { // Set up configuration sources. var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); //… Configuration = builder.Build(); }
同时咱们还能够看到一个环境变量env.EnvironmentName,这个设计也有利于咱们区分QA,INT,UAT,Production等不一样的运行环境。这一变量能够在项目配置中设置:
在代码中能够经过Configuration["hello"]的方式读取咱们以前定义的Appsettings。
三、默认自带IOC容器,统一依赖注入API
依赖注入技术从很大程度上使得代码更加模块化,会在必定程度上迫使你写出低耦合,SRP的代码,另外有着良好设计的代码也具有更好的可测试性。
ASP.NET Core本身内置了一个很是轻量级的IOC容器,例如如下代码将组建IEmailSender和ISmsSender分别注册在了容器中。
public void ConfigureServices(IServiceCollection services) { // Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddTransient<ISmsSender, AuthMessageSender>(); }
固然你能够引入第三方比较成熟的IOC容器,项目Dependency Injection定义了一组抽象,只须要将具体的IOC容器实现该抽象便可整合进ASP.NET Core中。就目前的状况来看ASP.NET Core内置的容器比较适合ASP.NET Core内部的组建使用,而实际业务依赖则可使用第三方更强大的容器来注册。
另外在ASP.NET Core新的设计中,不光Controller能够进行依赖注入,Filter,View以及ViewModel均可进行注入。这方面的内容比较多,也许会在单独的文章中进行介绍。
四、Middleware
这一设计借鉴自OWIN katana 项目的管道设计。什么是Middleware?下面这幅图很好的描述了Middleware是如何在http请求过程当中工做的。
在方法Configure中调用的内容均可以理解为Middleware:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { //… app.UseIISPlatformHandler(); //Middleware app.UseStaticFiles(); //Middleware app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); //Middleware }
注册一个Middleware有两种写法,好比你自定义了一个CustomerMiddleware,
第一种注册方法:
app.UseMiddleware<CustomerMiddleware>();
第二种则更经常使用:首先写一个扩展方法
public static class MiddlewareExtensions { public static IApplicationBuilder UseCustomerMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<CustomerMiddleware>(); } }
而后就能够这样使用了:app.UseCustomerMiddleware();
自定义Middleware请关注后续文章。
五、统一MVC和WebAPI
ASP.NET Core统一了MVC和WebAPI,这表如今这二者共用同一套代码,而且在开发过程当中不用再继承各自独立的Controller基类了。下面展现了如何在同一个Controller中编写MVC和WebAPI:
public class ServiceController : Controller { private readonly IConfigurationRoot _configurationRoot; public ServiceController(IConfigurationRoot configurationRoot) { _configurationRoot = configurationRoot; } public IActionResult Index() { return Content("hello world"); } public User GetUser() { var user = _configurationRoot.Get<User>("Users");// 读取appsettings.json中的对象 return user; } }
这一示例采用了构造器注入,为了让IOC容器注入IConfigurationRoot参数,咱们须要将该实例注册进IOC容器中:
public void ConfigureServices(IServiceCollection services) { //… services.AddInstance(Configuration); }
六、Razor页面中引入新的Tag Helpers
在以前的Razor页面中,咱们能够利用HtmlHelper扩展来完成数据绑定和页面展现,例如:
@Html.EditorFor (i => i.Email, new {htmlAttributes = new {@class = "form-control"}})
ASP.NET Core设计了新的方案:
<input asp-for="Email" class="form-control" />
这种写法更加接近HTML,对纯前段人员更加友好,也更利于结合一些前端的MVVM框架来使用。固然咱们还能够根据本身的需求编写自定义的Tag Helpers。使用Tag Helpers须要添加以下Nuget package:
"dependencies": { ... "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final"}
另一个例子对比:
HtmlHelpers:
@using (Html.BeginForm( "Register", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { role = "form" })) { @Html.AntiForgeryToken() @Html.ValidationSummary(true, "", new { @class = "text-danger" }) }
TagHelpers:
<form class="form-horizontal" method="post" role="form" asp-controller="Account" asp-action="Register"> <div class="text-danger" asp-validation-summary="ValidationSummary.All"></div> <!-- other tags or tag helpers --> </form>
七、其余一些特性如View Components,Caching…
本文介绍了下一代的ASP.NET版本ASP.NET Core 1.0而且对其新的特性作了归纳性的介绍,有助于.NET开发者对ASP.NET Core有一个全面的认识,随着我对ASP.NET Core的进一步了解还会对一些细节进行更进一步的补充,欢迎你们关注。