對於上面建立的這個Hello World應用來說,程式入口點由應用自身來提供,所以應用本身具有自我執行的能力。從應用託管(Host)的角度來講,這樣的應用同時負責對自身的託管。將應用與託管環境獨立起來其實是更好的選擇,因為這樣可以使同一個應用執行於不同的環境中。接下來我們就來演示如何為應用指定入口程式來達到應用與應用託管的分離。現在我們在HelloWorld目錄下建立兩個子目錄,並分別將它們命名為Project2和Project3。Project2代表應用本身,但是真正的入口程式則由Project3代表的專案提供,換句話說Project3是Project2 的宿主(Host)。兩個專案對應目錄及其原始檔結構:
1 2 3 4 5 6 7 |
Project2 Startup.cs project.json Project3 Program.cs project.json |
我們在Project2目錄下新增一個文字檔案並將其命名為Startup.cs,並按照如下的方式定義一個同名的型別。
1 2 3 4 5 6 7 8 9 10 11 12 |
using System; namespace Project2 { public class Startup { public void Configure() { Console.WriteLine("Hello World!"); } } } |
如上面的程式碼片斷所示,我們在Startup類中定義了一個Configure方法,我們希望在應用的入口程式在正常啟動並完成初始化之後自動回撥這個方法。對於應用自身來說,Startup是被啟動之後最先執行的型別,我們可以將一些針對應用的配置定義在Configure方法中。不過作為演示,我們僅僅讓此方法在控制檯上列印“Hello World”字樣。
我們說過任何一個被KRuntime視為專案的目錄必須包含一個project.json檔案,所以我們需要在Project2目錄下建立這個一個文字檔案,我們指定的入口程式就定義在這個檔案之中。如下所示的是這個project.json檔案的內容,我們僅僅在其commands配置項中新增了一個名為“RunFromProject3”的命令,對應的值為“Project3 Startup Configure”,其中Project3代表包含入口程式的程式集(專案Project3被編譯後生成的程式集)名稱,Startup和Configure組成的字串陣列將作為程式入口方法(Main)的引數,它們分別表示應用啟動程式所在的型別和對應的方法。我們同時在dependencies這個配置項中新增了針對Project3的專案依賴,這相當於在當前專案中新增了一個對應的專案引用。
1 2 3 4 5 6 7 8 |
{ commands:{ "RunFromProject3": "Project3 Startup Configure" }, dependencies:{ "Project3":"" } } |
接下來我們在Project3目錄下新增一個文字檔案並將其命名為Program.cs,然後安裝如下的形式定義這個作為程式入口的Program型別。與上面演示的第一個Hello World應用一樣,作為程式入口的型別必須命名為Program,其中包含一個靜態或者例項Main方法。如上面的程式碼片斷所示,Main方法的目的在於解析定義在Project2的Startup型別,然後據此型別例項化一個對應的物件並呼叫其Configure方法。型別和方法的名稱來源於Main方法的引數,而型別解析採用的程式集名稱與當前目錄(%CD%)名稱一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System; using System.IO; using System.Reflection; using System.Linq; namespace Project3 { public class Program { public void Main(string[] args) { string startup = args[0]; string configure = args[1]; string appBase = Directory.GetCurrentDirectory(); string appName = appBase.Substring(appBase.LastIndexOf('\\') + 1); Type startupType = Assembly.Load(new AssemblyName(appName)) .GetTypes().FirstOrDefault(type => type.Name == startup); startupType.GetMethod(configure) .Invoke(Activator.CreateInstance(startupType), new object[] { }); } } } |
在完成對作為入口程式的Program類的定義之後,我們同樣需要在Project3目錄下建立一個必需的project.json檔案。和第一個演示的Hello World應用一樣,這裡不需要任何的配置,所以直接將內容設定為“{}”即可。
在Project2的project.json檔案中,我們在其commands配置項中定義了一個命令,其實這個命令是為K.cmd定義,我們可以直接利用後者執行這個命令。與執行第一個Hello World程式一樣,我們開啟CMD命令列工具。在通過CD命令將Project2設定為當前目錄之後,我們按照如下的方式執行K RunFromProject3(RunFromProject3是在project.json中定義的命l令名稱)。從控制檯的輸出可以確定我們的應用被正常啟動了。
設定自定義的入口程式體現應用本身與應用託管之間的分離,它使我們可以建立獨立於託管環境的應用,並根據需要寄宿於任何一個我們希望的宿主程式下,對於Web應用來說這一點尤為重要。對於之前的Web應用來說,IIS是它們唯一的宿主,但是ASP.NET 5應用卻可以將我們指定的入口程式作為宿主。如果將應用寄宿於我們指定的宿主程式,這樣的寄宿方式被稱為Self-Host,接下來我們將通過一個具體的例子來演示如何定義一個簡單的ASP.NET MVC應用,並採用Self-Host的方式啟動它。