[英]MVC Controller Generic injection with AutoFac
我對使用Autofac的DI相當新,並想知道以下是否可行
我想創建一個接收注入類型的通用控制器和動作。 我不想要一個注入類型的實例,但只需要它的類型,這將是一個預期接口的實現。
我也想把這個泛型類型傳遞給ViewModel,但這完全是另一個主題,但是如果有一些天才可以解決這兩個問題,那將是非常好的。
public ContractorController<T> : Controller
where T : IContractor{
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
應通過http://mysite.com/Contractor/New
調用此控制器
我一直在尋找使用AutoFac注冊泛型,但似乎問題是AutofacControllerFactory只實現了GetControllerInstance(),期望從GetController()或CreateController()傳遞給它的控制器類型,不確定哪個或哪個不同在他們之間。 這些方法從RoutData接收控制器的名稱作為字符串,並返回相應的.NET類型,給出URL, http://mysite.com/Contractor/New
://mysite.com/Contractor/New是controller = Contractor,因此ContractorController不能與GetController()匹配或CreateController()和therfore將null傳遞給GetControllerInstance(),這意味着AutofacControllerFactory不會嘗試解析該類型。
我想我必須創建一個派生自AutofacControllerFactory的自定義Controller Factory,重寫GetController()或CreateController()並執行我自己的映射,從控制器名稱到泛型類型。 就像是
if(controllerName ==“Contractor”)返回System.Type.GetType(“UI.Controllers。”+ controllerName +“Controller`1”);
當我調試這個時,我可以看到這個代碼正在找到通用控制器並返回它。
我想我可以只注冊類似的類型
builder.RegisterType<FakeContractor>().As<IContractor>();
builder.RegisterGeneric(typeof(ContractorController<>));
但是我收到以下錯誤
The Autofac service
'UI.Controllers.ContractorController`1'
representing controller
'ContractorManagement.UI.Controllers.ContractorController`1'
in path '/Contractor/New' has not been registered.
所以我想我可能正在咆哮錯誤的樹。 任何人都可以在沒有拔牙的情況下闡明如何做到這一點
謝謝
我不完全確定你為什么要使用通用的控制器。 在Mvc中實際上不支持在Controller上使用通用 - 或者至少涉及支持路由路徑。 也許您可以提供有關該方法背后原因的更多信息?
它看起來像是你想要一個支持不同類型的模型綁定的控制器。 接下來的問題是這些類型是否在公共接口或基類之間有所不同。
如果是這種情況,對於Mvc2,請查看IocModelBinder信息 。 這將非常適合Autofac。 這將允許類型在post或get上進行模型綁定,允許您使用autofac注入服務。
如果您想通過一個共同的基礎來改變類型 - 支持各種具體的視圖模型 - 那么請查看MvcContrib中的DerivedTypeModelBinder 。 有一個版本適用於Mvc 1,2,現在MvcContrib for Mvc3有一個很好的示例應用程序。 Mvc3實現也更快 - 速度以前不是問題,它只是一個更有效的識別過程。
也許這不是你問題的直接答案,但這是使用我見過和使用的通用控制器的唯一可行方法:
public abstract class ContractorControllerBase<T> : Controller where T : IContractor {
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
public class FakeContractorController : ContractorControllerBase<FakeContractor> {
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.