本文將對微軟下一代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的進一步瞭解還會對一些細節進行更進一步的補充,歡迎你們關注。