2014年11月2日 星期日

IController、ControllerBase 和 Controller

當在 ASP.NET MVC 專案建立一個 Controller 時,Visual Studio 會產生一個以 "Controller" 為結尾並繼承 Controller 抽象類別的新類別,例如:
HomeController : Controller

以下為繼承關係
Controller 抽象類別 --> ControllerBase 抽象類別 --> IController 介面

IController
唯一的目的在 Controller 接收請求時,Execute() 方法會執行一些code
// 摘要: 
//     定義控制器所需的方法。
public interface IController
{
    // 摘要: 
    //     執行指定的要求內容。
    //
    // 參數: 
    //   requestContext:
    //     要求內容。
    void Execute(RequestContext requestContext);
}

Execute() 方法在 MvcHandler 的 ProcessRequest() 方法中被調用;Execute() 方法接收 RequestContext 類別參數,RequestContext 類別封裝了 RouteData(在UrlRoutingModule中解析Http產生的路由數據)與 HttpContext 用來表示當前請求的上下文。


ControllerBase
定義了 Controller 使用到的部分公共屬性,比如:用來保存臨時數據的 TempData,用來返回到 View 中的 Model 數據對象 ViewBag、ViewData;並且初始化了ControllerContext 對象,用來作為後續Controller使用的數據容器和操作上下文


public abstract class ControllerBase : IController
{
    //省略其他成員
 
    protected virtual void Execute(RequestContext requestContext)
    {
        if (requestContext == null)
        {
            throw new ArgumentNullException("requestContext");
        }
        if (requestContext.HttpContext == null)
        {
            throw new ArgumentException(MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, "requestContext");
        }
 
        VerifyExecuteCalledOnce();
        Initialize(requestContext);
 
        using (ScopeStorage.CreateTransientScope())
        {
            //執行ExecuteCore方法
            ExecuteCore();
        }
    }
    // 該方法在衍生的Controller類中實現
    protected abstract void ExecuteCore();
 
    protected virtual void Initialize(RequestContext requestContext)
    {
        ControllerContext = new ControllerContext(requestContext, this);
    }
    internal void VerifyExecuteCalledOnce()
    {
        if (!_executeWasCalledGate.TryEnter())
        {
            string message = String.Format(CultureInfo.CurrentCulture,
              MvcResources.ControllerBase_CannotHandleMultipleRequests, GetType());
            throw new InvalidOperationException(message);
        }
    }
    void IController.Execute(RequestContext requestContext)
    {
        Execute(requestContext);
    }
}

ControllerBase 實作了 Execute() 方法,負責建立 ControllerContext(提供MVC當前請求的具體上下文),ControllerBase 以“顯式介面實現”的方式定義了Execute() 方法,該方法在內部直接調用受保護的 Execute() 虛方法,而後者最終會調用抽象方法 ExecuteCore() 方法。

Controller 繼承自 ControllerBase 並實現抽象方法ExecuteCore()

沒有留言: