讓 ASP.NET MVC 支援 HotSwap

來源:互聯網
上載者:User
導讀:

  

  在HowToStart那帖中,我提到了ASP.NET MVC的問題 :

  如果修改一次Controller的代碼,就導致ASP.NET重啟一次 , 那麼會不會很麻煩?

  有時候一個項目大一點, ASP.NET啟動一次需要幾十秒, 那樣的等待真的很浪費時間.

  與思歸的交談中, 他提到了HotSwap的概念. "熱插拔" - 編寫代碼後不需要重新編譯或重啟ASP.NET.

  怎樣實現這個功能呢? 現在MVC的文檔很少. 只能通過Reflector去找答案了.

  一個Request,從Url, 一直到了具體的 Controller , 經過了那些步驟呢?

  下面列出了這個步驟的詳細:

  1. Url

  2. RouteTable

  3. MvcRouteHandler

  4. MvcHandler

  5. ControllerBuilder

  6. ControllerFactory

  7. Controller

  這個過程中, MvcRouteHandler 是串連 RouteTable 和 MvcHandler 的橋樑.

  MvcHandler則根據傳遞過來的資訊, 根據某種規則, 從所有的Assembly中找到對應的Controller類

  然後把類型資訊傳遞給 ControllerBuilder/ControllerFactory , 用於指定一個更具體的Controller.

  (類似RuntimeEntity那篇文章說的子類化模式..)

  看來, 需要對MvcHandler下手了. 而 MvcRouteHandler 則就是 MvcHandler 的 Factory.

  所以同時也要編寫MvcRouteHandler的實現 :

  public class HotSwapMvcRouteHandler : System.Web.Mvc.MvcRouteHandler

  {

  protected override IHttpHandler GetHttpHandler(System.Web.Mvc.RequestContext requestContext)

  {

  HotSwapMvcHandler handler = new HotSwapMvcHandler();

  handler.RequestContext = requestContext;

  return handler;

  }

  }

  public class HotSwapMvcHandler : System.Web.Mvc.MvcHandler

  {

  protected override Type GetControllerType(string controller)

  {

  string name = controller + "Controller";

  string file = "~/Controllers/" + name + ".cs";

  if (!System.IO.File.Exists(HttpContext.Current.Server.MapPath(file)))

  return base.GetControllerType(controller);

  System.Reflection.Assembly assembly = System.Web.Compilation.BuildManager.GetCompiledAssembly(file);

  return assembly.GetType(name, true, true);

  }

  }

  上面2個類, 寫在App_Code裡就OK了, 然後, 需要修改一下 RouteTable 的寫法:

  RouteTable.Routes.Add(new Route

  {

  Url = "[controller]/[action]/[id]",

  Defaults = new { action = "Index", id = "" },

  RouteHandler = typeof(HotSwapMvcRouteHandler)

  });

  注意一下 , RouteHandler由MvcRouteHandler替換成 HotSwapMvcRouteHandler 了.

  這樣HotSwapMvcRouteHandler的代碼就能夠被執行, 返回HotSwapMvcHandler

  HotSwapMvcHandler 這裡得到了一個 controller 的參數, 就是它了.

  我們要做的事情,就是根據它 , 找到我們想要的 Controller

  上面的GetControllerType的具體實現也實在太簡單了.

  如果存在 ~/Controllers/XxxControler.cs

  就編譯它, 然後直接返回 XxxController 類型.

  否則就按傳統的方式去尋找對應的類.

  ----

  OK , 就這樣2步, 就實現了在 ~/Controllers/ 中存放Controller代碼的目的了.

  重溫一下這2步:

  1. App_Code中增加 HotSwapMvcRouteHandler , HotSwapMvcHandler

  2. Global.asax中修改RouteTable的定義

  然後,就可以在 ~/Controllers/ 下增加 TestController.cs , 內容是

  public class TestController : Controller

  {

  [ControllerAction]

  public void Index()

  {

  ViewData["typename"] = this.GetType().AssemblyQualifiedName;

  ViewData["version"] = "version5";

  RenderView("index");

  }

  }

  然後建立對應的 ~/Views/Test/index.aspx 把東西顯示出來:

  index.aspx

  

  <%=ViewData["version"] %>

  

  <%=ViewData["typename"] %>

  

  <%=Application["mystr"] = "1" + Application["mystr"]%>

  顯示:

  version5

  --------------------------------------------------------------------------------

  TestController, App_Web_testcontroller.cs.39ee6e8a.c0bebgfm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

  --------------------------------------------------------------------------------

  111

  不斷地重新整理它, Application["mystr"]就會越來越長.

  然後去修改 TestController.cs 把. 把ViewData["version"] = "version123";

  那麼就會立刻生效, 顯示version123,而Application["mystr"]沒有重設, 證明ASP.NET並沒有重啟.

  想提高開發的方便性的朋友 , 不妨試試上面的代碼.

本文轉自

http://blog.joycode.com/lostinet/archive/2007/12/11/112496.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.