簡體   English   中英

MVC控制器使用AutoFac進行通用注入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM