3

以我控制器,所有相關性通過注射接受,繼Dependency inversion principle,除了一個,映射器類,其由構造函數實例:我的Mapper類應該注入到我的控制器中,還是可以直接實例化它?

public class HomeController : Controller 
{ 
    private readonly ISomeAppService SomeAppService; 
    private readonly Mapper Mapper; 

    public HomeController(ISomeAppService someAppService) 
    { 
     SomeAppService = someAppService; 
     Mapper = new Mapper(); 
    } 

    public ActionResult Index() 
    { 
     var someList = SomeAppService.GetSomeList(); 
     var someListDTO = Mapper.Map(someList); 
     return View(new HomeIndexViewModel(someListDTO)); 
    } 

SomeAppService是一個應用層的服務中的前我域層。 Mapper接收域對象並返回視圖使用的DTO。

我的推理是,自從ViewModel represents only the data that you want to display on your view/page以來,我無法預見到任何需要用別的東西來替換Mapper的情況,或者這可能對測試不利。我也看不到這個Mapper類在任何其他表示層上被重用,因爲其他視圖可能與Web表示不同。對我來說,它感覺作爲控制器的一部分。

的問題是,這是正確的?我是否需要通過依賴注入來接收Mapper?我需要爲它定義一個接口嗎?如果是這樣,爲什麼?我想遵守固體原則,但我想知道他們是否以及如何在這裏應用。

+0

一種方法是問問自己做什麼SANS映射類。大多數人寫一個私人函數來完成這項工作,或者如果對象足夠簡單,他們只需將其新增並進行內聯映射即可。然而,這個特殊情況看起來很詭異的原因是你的類被稱爲「Mapper」,並沒有進行任何特定的初始化(指示它被映射的對象),所以我只能假定它具有映射所有種類的知識對象,也許有些與這個控制器無關。這可能是這感覺有點臭的原因。 –

回答

3

個人而言,我會建議你注射映射實例。這正是IoC容器設計用於管理的內容。

沒有理由爲它的控制器內,並在其當前狀態違背了開閉原則和SOLID原則控制反轉被實例化。

使用IoC容器注入時,你將獲得的好處是:

改善測試

通過注入您的實例映射到你的控制器,你將能夠爲它創建以嘲弄編寫更好的測試。雖然您現在可以測試您的控制器,但您無法在任何情況下在控制器內測試您的映射器實例。

改進的可擴展性

當你想能夠構造函數的參數傳遞到你的映射器在短短几個月的時間,會發生什麼?你需要經歷所有的控制器動作並更新你的構造函數。通過將創建Mapper實例的責任傳遞給IoC容器,您將創建一個配置點,這意味着可以在一個位置管理和配置對Mapper類的任何進一步修改或更改。

有一兩件事可以肯定 - 這就是預期壽命超過數個月的時間大部分軟件 - 它會改變。儘管您目前可能看不到您的映射器實例發生變化的原因,但您可以儘可能方便地進行更改,這是設計軟件的好習慣。你必須改變的東西越多,最有可能是你破壞某些東西或引入錯誤的機會。

+0

感謝您的好評。我從來沒有想到我可能需要在某個時候向mapper傳遞參數,這是一個很好的例子。我肯定會將它注入我的控制器。有一件事對我來說並不是很清楚,你是指「現在,你無法在任何情況下在控制器內測試你的映射器實例」是什麼意思? –

+0

斑點!你沒有足夠的代表嗎?編輯帖子呢? –

+1

足夠公平:)回答你的問題 - 由於你的映射器實例是在控制器內部實例化的,並且沒有被注入,所以你無法嘲笑它;所以,舉例來說,你將無法嘲笑它編寫一個單元測試,測試你的控制器如何處理'Mapper.Map'返回一個空引用。 –

0

隨着所有好處,@JoeMighty上面給了,我想補充一點,通過注入在控制器映射器,你可以外部化Mapper.Map定義,釋放該責任的控制器。此外,您可以通過控制注入的Mapper的生命週期來緩存映射定義,因此Mapper不必爲每個請求創建定義。想想這個

相關問題