在MVC4中,您可以創建自定義控制器工廠以在創建控制器實例時捕獲控制器實例。您可以將其用作單個構圖點,而不必在每個控制器中執行此操作。
繼承自System.Web.Mvc.DefaultControllerFactory
,創建自定義控制器工廠。覆蓋GetControllerInstance
方法,並讓基函數爲您創建控制器。現在你可以讓你的依賴注入引擎組成控制器。
public class AreaControllerFactory : DefaultControllerFactory
{
// We use a controller factory to hook into the MVC pipeline in order to get a reference to controllers
// as they are being created. We inherit from the default controller factory because we do not want to
// have to locate the appropriate controllers ourself (we only want a reference to it). Once we have a
// reference, we simply hand the controller off for composition.
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
IController controller = base.GetControllerInstance(requestContext, controllerType); // create the controller
if (controller != null)
{
var container = ...; //construct your composition container
container.ComposeParts(controller); //compose your controller
}
return controller;
}
}
在Global.asax.cs
註冊控制器工廠在Application_Start
方法。
var controllerFactory = new AreaControllerFactory();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
爲了通過區篩選組合物的目的,我建立一個自定義,全局區組分辭典(例如區域名稱,適用類型的列表的字典)爲每個區域。
// NOTE:ComposablePartCatalog is MEF specific, change as needed
internal static class AreaComponents
{
/// <summary>
/// A list of Area name, catalog pairs.
/// Each Area can provide a custom list of components to import from.
/// </summary>
internal static readonly Dictionary<string, ComposablePartCatalog> AreaCompositionCatalogs =
new Dictionary<string, ComposablePartCatalog>();
}
填充字典中的每個區域的AreaRegistration
實施RegisterArea
方法裏面。
public class XAreaRegistration : AreaRegistration
{
public override void RegisterArea(AreaRegistrationContext context)
{
/* ... Standard route logic ... */
// Set up an MEF catalog with Area components
var xCatalog = new AssemblyCatalog(
typeof(MyPluginsNamespace.ArbitraryTypeToLookupAssembly).Assembly);
AreaComponents.AreaCompositionCatalogs["X"] = xCatalog;
}
}
使用該字典來構建組合容器給定控制器時,在我的自定義控制器工廠選擇組成的對象適當的子集。
// Capture current area name
System.Web.HttpContextBase contextBase = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
System.Web.Routing.RouteData routeData = System.Web.Routing.RouteTable.Routes.GetRouteData(contextBase);
object areaObject = routeData.DataTokens["area"];
string areaName = areaObject as string ?? string.Empty;
// Create a composition container specific to this area
ComposablePartCatalog areaCatalog =
AreaMefComponents.AreaCompositionCatalogs.ContainsKey(areaName) ?
AreaMefComponents.AreaCompositionCatalogs[areaName] : null;
var container = new CompositionContainer(areaCatalog);
最終,您必須在某處指定服務的類型。一般來說,控制器是單獨負責的。 DI值得嗎?它解決了什麼問題? –
因此,控制器正在使用共享服務類型。存儲庫將被注入到指向特定數據源的服務中。我現在將編寫一個示例應用程序並將其鏈接到該問題 –