技术开发 频道

让 ASP.NET MVC 支持 HotSwap

【IT168 技术文档】在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)
});


0
相关文章