(此文章同時發表在本人微信公眾號“dotNET開發經驗談”,歡迎右邊二維碼來關注。)
題記:正在構思一個中間件的設計,考慮是否既可以使用最新的技術,也可以兼顧傳統的部署模式。所以有了這個問題(包括衍生問題)的提出和解決方法。
眾所周知,ASP.NET Core采用了和傳統ASP.NET不同的托管和HTTP處理方式,即把服務器和托管環境完全解耦。
ASP.NET Core內置了兩個HTTP服務器實現,一個是基於libuv實現的Kestrel(支持跨平台),一個是基於Windows HTTP Server API實現的WebListener(僅支持Windows)。
而托管環境可以和服務器不相關,一般情況是自托管,或者托管到IIS/IISExpress中(此處的IIS僅作為反向代理把請求轉發給所使用的服務器實現)。
因此,打算以Windows Service這種比較傳統的方式來部署ASP.NET Core的Web應用也是可行的(本質還是自托管,只是啟動進程並非控制台程序,而是一個Windows Service)。這不,微軟就很貼心的提供了一個Nuget來支持:Microsoft.AspNetCore.Hosting.WindowsServices,它的源碼在:https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNetCore.Hosting.WindowsServices。
使用它也很簡單:
public static class CustomWebHostWindowsServiceExtensions { public static void RunAsCustomService(this IWebHost host) { var webHostService = new CustomWebHostService(host); ServiceBase.Run(webHostService); } } host.RunAsCustomService();
把ASP.NET Core應用托管到Windows Service中,就這麼簡單!
不過,我想從我的場景來談談為什麼我有托管到Windows Service的需求。這幾天在構思一個中間件(包含多個組件)的架構,考慮到初期會以比較傳統的方式來部署,後期有可能跨平台,並且希望組件之間能夠相對獨立和解耦。所以,最自然的想法就是架構設計為微服務,基於ASP.NET Core實現(未來不排除使用其他技術棧)。部署的話,初期分離部署為多個Windows Service,後期也可以很平滑的過度到容器或者類似Service Fabric這樣的微服務運行平台中。
基於這樣的設計考慮,要解決的第一個問題就是是否可以把ASP.NET Core應用托管到Windows Service中(上面已經驗證了),第二個問題是是否可以根據環境條件跑在不同的啟動進程中,第三問題是是否可以同時支持多種運行時。2,3個問題要解決其實也非常簡單。
第二個問題的解決辦法如下:
就是這麼簡單粗暴。
.NET Core本來就支持一個項目多個運行時,就算把net46和netcoreapp1.0混合也是可以的。具體方法如下:
為了避免在文章中貼大段的源代碼,大家轉到GitHub中去看示例代碼吧:https://github.com/heavenwing/HostingAspCoreAsWindowsService