首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET MVC 2 擴展點深度解析 (一):Controller Factory 控制器工廠與依賴注入

     編輯:關於ASP.NET

Controller Factory 是 ASP.NET MVC 負責建立 Controller 實例的核心擴展點。預設 DefaultControllerFactory 使用 Activator.CreateInstance 需要無參數建構函式,無法支援建構函式注入。自訂 Controller Factory 可整合 DI 容器(Unity、Autofac、Ninject 等)實現依賴注入。

預設行為與問題

public class HomeController : Controller {
    private readonly IProductService _service;
    
    public HomeController(IProductService service) { // 有參數建構函式
        _service = service;
    }
}

直接執行會拋出:MissingMethodException: No parameterless constructor defined for this object。

缺少無參數建構函式錯誤

自訂 Controller Factory 實作

public class UnityControllerFactory : DefaultControllerFactory {
    private readonly IUnityContainer _container;
    
    public UnityControllerFactory(IUnityContainer container) {
        _container = container;
    }
    
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
        if (controllerType == null) {
            throw new HttpException(404, $"找不到控制器: {requestContext.RouteData.Values["controller"]}");
        }
        // 從容器解析,支援建構函式注入
        return (IController)_container.Resolve(controllerType);
    }
}

整合 Unity 容器完整設定

// Global.asax
public class MvcApplication : HttpApplication {
    private static IUnityContainer _container;
    
    protected void Application_Start() {
        _container = new UnityContainer();
        RegisterTypes(_container);
        
        ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(_container));
        
        RegisterRoutes(RouteTable.Routes);
    }
    
    private void RegisterTypes(IUnityContainer container) {
        container.RegisterType();
        container.RegisterType();
        // 註冊 Controller 本身(可選,生命週期管理)
        container.RegisterType(new TransientLifetimeManager());
    }
}

繼承 DefaultControllerFactory vs 實作 IControllerFactory

方式優點缺點
繼承 DefaultControllerFactory保留預設尋找邏輯(命名空間慣例、Area 支援),僅覆寫實例化受限於基底類別設計
實作 IControllerFactory完全控制尋找與建立流程需自行實作命名空間搜尋、快取等邏輯

進階:多租戶/區域感知 Controller Factory

public class MultiTenantControllerFactory : DefaultControllerFactory {
    protected override Type GetControllerType(RequestContext requestContext, string controllerName) {
        // 依租戶/區域動態決定命名空間
        string tenant = requestContext.RouteData.Values["tenant"] as string;
        string[] namespaces = tenant != null 
            ? new[] { $"MyApp.Tenants.{tenant}.Controllers" }
            : new[] { "MyApp.Controllers" };
        
        return base.GetControllerType(requestContext, controllerName, namespaces);
    }
}

ASP.NET Core 對比

ASP.NET Core 內建 DI 容器,Controller 直接支援建構函式注入,無需自訂 Factory。遷移時可直接移除自訂 Factory 代碼,改用 services.AddControllers() 並註冊服務至 IServiceCollection。

常見錯誤

  • 忘記在 ControllerBuilder.Current.SetControllerFactory 註冊
  • DI 容器未註冊 Controller 型別(Transient 生命週期)
  • 容器解析失敗拋出異常未處理,導致黃色死機畫面
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved