BuildManagerCompiledView 透過 IViewPageActivator 建立 View 頁面實例。預設 DefaultViewPageActivator 使用 DependencyResolver.Current 解析型別,若失敗則 Activator.CreateInstance。此機制允許透過自訂 IDependencyResolver 整合 IoC 容器。
public class NinjectDependencyResolver : IDependencyResolver
{
public IKernel Kernel { get; private set; }
public NinjectDependencyResolver() { Kernel = new StandardKernel(); }
public void Register<TFrom, TTo>() where TTo : TFrom
=> Kernel.Bind<TFrom>().To<TTo>();
public object GetService(Type serviceType) => Kernel.TryGet(serviceType);
public IEnumerable<object> GetServices(Type serviceType) => Kernel.GetAll(serviceType);
}
// Global.asax 註冊
DependencyResolver.SetResolver(new NinjectDependencyResolver());
public abstract class ResourceReader
{
public abstract string GetString(string name);
}
public class DefaultResourceReader : ResourceReader
{
public override string GetString(string name)
=> Resources.ResourceManager.GetString(name); // 自動依 Culture 選擇 .resx
}
public abstract class LocalizableViewPage<TModel> : WebViewPage<TModel>
{
[Inject] // Ninject 屬性注入標記
public ResourceReader ResourceReader { get; set; }
}
<system.web.webPages.razor>
<pages pageBaseType="MyApp.LocalizableViewPage">
<namespaces>...</namespaces>
</pages>
</system.web.webPages.razor>
var resolver = (NinjectDependencyResolver)DependencyResolver.Current;
resolver.Register<ResourceReader, DefaultResourceReader>();
@model MyModel
<h1>@ResourceReader.GetString("HelloWorld")</h1>
ViewResult。RazorViewEngine.FindView 找到 .cshtml 虛擬路徑。RazorView.Render 呼叫 BuildManagerCompiledView.Render。DefaultViewPageActivator.Create 透過 DependencyResolver.Current.GetService(viewType) 解析。NinjectDependencyResolver.GetService → Kernel.TryGet 返回 LocalizableViewPage 實例。[Inject] 屬性,自動注入 DefaultResourceReader 實例。ResourceReader.GetString 取得當前文化資源字串。ASP.NET MVC Razor 引擎透過 IViewPageActivator + IDependencyResolver 開放 View 激活管線。自訂 NinjectDependencyResolver 並設定 View 基類與 [Inject] 屬性,即可實現 View 層級的相依性注入,優雅解決多語系、共用服務等跨領域關注點。