
Katana-武士刀,寓意:快、準、狠!
按照常規,我們一般編寫的 asp.net 應用程序會部署在 IIS 上(有點傻的描述),在 ASP.NET 應用程序中,我們會大量使用 HttpContext 對象,比如:HttpContext.Current.Request 用來獲取當前 Http 請求對象,這些對象的獲取都來自于 System.Web 程序集,而這個程序集依附于 IIS,也就是說,ASP.NET 應用程序依附于 IIS,在之前了解過 runAllManagedModulesForAllRequests,知道它是 Web.config 中配置的一個節點,具體什么意思呢?就是管理所有請求與處理模塊的一個開關,當一個請求到達 IIS,它會把這個請求所要進行的處理分配給特定的處理模塊,然后進行處理,也就是配置文件中 system.webServer 下的 modules 與 handlers 配置,或者我們可以直接在 IIS 的模塊管理界面進行配置,比如管理身份驗證的 DefaultAuthentication 模塊,對應類型為 System.Web.Security.DefaultAuthenticationModule,不經意間,你又發現 System.Web 的身影了。
我們知道,ASP.NET 應用程序與 IIS 都依賴于 .NET Framework,而 ASP.NET 應用程序所要進行的處理都來自于 IIS,這其中的關系就像“亂麻”一樣,造成更深一步的依賴,讓他們不得不捆綁“在一起”。其實說白了,ASP.NET 應用程序與 IIS 的關系,有點像白蟻與蟻后的關系,什么意思呢?白蟻是蟻后生的,并且它的一些活動都是由蟻后進行控制,沒有蟻后,也就沒有白蟻,離開蟻后,白蟻也不能進行生存,比如白蟻跑到行軍蟻的巢穴,在不被行軍蟻吃掉的情況下,能生存嗎?顯然不可以。我們理想的狀態是,既然大家都是螞蟻類,就應該和諧共處,我到你那住幾天,你來我這玩幾天,這些都應該是可以的,而這樣的前提條件是,大家需要一個規約來進行共同遵守,誰也不能越過它,否則大家都玩完,這個規約就是 Owin(Open Web Interface for .Net)。
關于 Owin 的資料網上有很多,這邊就不重復造輪子了,它其實是 Web 應用程序和服務器之間交互的一種協定,用來解耦他們之間的依賴關系,交互方法簽名為 AppFunc(應用程序委托):
AppFunc = Func<IDictionary<string, object>, Task>;IDictionary< string, object > 是什么東西呢?你可以把它看作是 Web 應用程序和服務器直接交互處理用到的一個集合數據,首先,Owin 定義了 Web 應用程序和服務器之間的一個管道(pipeline),而這個集合對象就是這個管道之中進行傳輸的數據,我們知道 Web 應用程序的處理其實就是對請求的進行處理,服務器的作用也就是對請求進行各種各樣的處理,如果我們可以把請求數據進行“規范化”,那不同的服務器都可以進行處理同樣 Web 應用程序的請求,這就是 Owin 最基本的體現,這個基礎請求數據就是(Key/Value):
以上是 Request Data 的鍵/值說明,并不是全部,只是最基本的,全部聲明請查看:http://owin.org/spec/spec/owin-1.0.0.html。
看到這,你會不會這樣想:既然協議是公開的,如果我按照這種協議,是不是也可以自己實現一個 Web 服務器?答案是當然可以,Jesse Liu 就曾搞過:一不小心寫了個WEB服務器,但如果是從頭到尾自己搭建一個 Web 服務器,還是有些難度的。上面說了一大堆 Owin 的東西,而且是“虛”的東西,因為它只是定義,并不包含任何實現,而 Katana 是微軟基于 Owin 協議實現的一個組件和框架集合,是實實在在的東西,在說 Katana 之前,需要先說明一下 Katana 的“歷史”,因為你會發現,在新建的 ASP.NET 5 項目中,沒有了它的“身影”,這是怎么回事呢?
Owin 和 Katana 是 ASP.NET 5 之前出來的東西,以前的 Katana 源碼地址是:http://katanaproject.codeplex.com/,最近一次的代碼提交時間是 2014/8/20,可以看出,這個 Katana 代碼庫微軟現在基本上已經不維護了,那它現在跑哪里去了?首先,以前我們在 ASP.NET 應用程序中使用 Katana,需要引入的程序集是 Microsoft.Owin.,而在 ASP.NET 5 應用程序中,變成了 Microsoft.AspNet.,并且版本已初始化為 v1.0.0.,最重要的是,代碼托管也已經被拆分了。
Old Katana Source:
New 'Katana' Source:
其實你會發現,在 ASP.NET 5 中,已經沒有了 Katana 的“身影”,甚至你也很難發現 Owin 這個單詞了,為什么會這樣?微軟為什么要“模糊”它們,首先,對于 Katana 這個名詞,我覺得對于微軟來說它現在更加像一個“代號”,或者稱之為一種“象征”,代表著 ASP.NET 應用程序與 IIS 之間糾纏的結束,而不是具體實質化的東西,這也就是為什么之前程序集命名是 Microsoft.Owin.,而不是 Katana.,而對于 Owin 來說,協議是微軟自己定義的,在之前的 ASP.NET 應用程序中,你如果使用 Owin,其實是有些雞肋的,因為 ASP.NET 并沒有和 IIS 進行很好的斬斷關系,雖然項目中有個 Startup.cs 文件,但你會發現,還有一個 Web.config 文件,而 ASP.NET 5 是“進化完全版”的 Owin,其實你會發現,你很難定義 ASP.NET 5 到底是什么了?你可以把它看作是 Owin,也可以看做是 ASP.NET 應用程序,又或者是一個 Web 服務器,這些都是有可能的,因為它是一個組件型的 ASP.NET,充滿著無限可能性,這才是新一代的 ASP.NET-ASP.NET 5。
我們來看一張圖:

上面是 Katana 的項目體系結構圖,分別來看一下:
我們再來看一個更詳細的:

我們再來看下 ASP.NET 5 的 project.json 配置文件:
"dependencies": { "Microsoft.AspNet.Server.IIS": "1.0.0-*", "Microsoft.AspNet.Mvc": "6.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-*", "Microsoft.AspNet.Security.Cookies": "1.0.0-*", "Microsoft.AspNet.Security.Facebook": "1.0.0-*", "Microsoft.AspNet.Security.Google": "1.0.0-*", "Microsoft.AspNet.Security.MicrosoftAccount": "1.0.0-*", "Microsoft.AspNet.Security.Twitter": "1.0.0-*", "Microsoft.AspNet.StaticFiles": "1.0.0-*", "EntityFramework.SqlServer": "7.0.0-*", /*For Mono*/ "EntityFramework.InMemory": "7.0.0-*", "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-*", "Microsoft.Framework.OptionsModel": "1.0.0-*", "Microsoft.AspNet.SignalR.Server": "3.0.0-*", "Microsoft.Framework.Cache.Memory": "1.0.0-*" },上面是微軟 MusicStore dependencies 的部分配置,注意 Microsoft.AspNet 之前的名字叫 Microsoft.Owin,從 Hosts 開始說起,在配置信息中,我們并沒有發現它的身影,因為我們已經配置了 Microsoft.AspNet.Server.IIS,指定 IIS 來管理 Owin 組件的啟動、加載等配置,我們也可以 SelfHost,ASP.NET 5 Hosting 的源碼地址:https://github.com/aspnet/Hosting,它的作用是什么呢?從項目說明上就可以看出:Code for hosting and starting up an ASP.NET application. 再來看 Server,其實就是我們配置文件中的 Microsoft.AspNet.Server.WebListener,負責監聽并處理分發請求,而 Middleware 中間件就是 Microsoft.AspNet.Security、Microsoft.AspNet.StaticFiles 之類的處理模塊,可以有很多,但其實常規的模塊就那幾個,Application 就是 Microsoft.AspNet.Mvc,當然也可以是 WebAPI 等其他應用程序,需要的話,直接添加對應的模塊就可以了,這種分析過程來看,其實 ASP.NET 5 又可以看作是一個容器,它可以是一個 Web 應用程序,又可以是一個 Web 服務器,想怎么變就怎么變,看我七十二變?
最后,再來說下 Startup.cs 中的兩個重要方法:
// This method gets called by the runtime.public void ConfigureServices(IServiceCollection services){ // Add EF services to the services container. services.AddEntityFramework(Configuration) .AddSqlServer() .AddDbContext<ApplicationDbContext>(); // Add Identity services to the services container. services.AddDefaultIdentity<ApplicationDbContext, ApplicationUser, IdentityRole>(Configuration); // Add MVC services to the services container. services.AddMvc(); // Uncomment the following line to add Web API servcies which makes it easier to port Web API 2 controllers. // You need to add Microsoft.AspNet.Mvc.WebApiCompatShim package to project.json // services.AddWebApiConventions();}// Configure is called after ConfigureServices is called.public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory){ // Configure the HTTP request pipeline. // Add the console logger. loggerfactory.AddConsole(); // Add the following to the request pipeline only in development environment. if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase)) { app.UseBrowserLink(); app.UseErrorPage(ErrorPageOptions.ShowAll); app.UseDatabaseErrorPage(DatabaseErrorPageOptions.ShowAll); } else { // Add Error handling middleware which catches all application specific errors and // send the request to the following path or controller action. app.UseErrorHandler("/Home/Error"
新聞熱點
疑難解答