2013-02-12 47 views
3

我已閱讀或試圖閱讀太多「如何」,並且已經完全無處可去。統一? System.Web.Http.Dependencies? Ninject? StructureMap?啊。我只想要簡單的工作!我無法弄清楚這是什麼現狀。有非常不同的方法,這些例子似乎不完整。哎呀,最好的領導有一個樣本項目...我無法加載VS2010或2012. ARG!我每天3/4的時候都會覺得應該有半個小時的時間,然後繼續前進!這只是水暖!如何爲MVC4/VS2012/Web API注入控制器

我有一個基於泛型的存儲庫來處理大量支持相同操作的數據集。

IRepository

我想控制其庫中的每個數據集被綁定到。這將允許我將所有內容綁定到測試XML存儲庫,隨着項目的進展將它們轉換到SQL存儲庫。

我當然希望得到一些幫助得到這個去!謝謝!

+0

我只是刪除一切,並試圖再次統一,因爲這是我來最接近的一次。在預感上,我刪除了一個構造函數,它帶有參數,我認爲它工作。我不知道爲什麼當空的構造函數可用時它鎖定在構造函數上(我所做的只是評論其他)。明天早上將繼續關注此事。 – 2013-02-12 21:48:29

回答

3

聽起來像你是在我幾年前的狀態。

請注意,如果您需要更多幫助,我會向您發送一些代碼。很難把所有的代碼放在這裏。

我試着解釋我正在開發的項目中的當前體系結構。這篇文章有點冗長,但我想給你一個關於如何使用IOC在很多方面可以幫助你的大局。

所以我使用Ninject。在嘗試使用Castle Windsor一段時間後,我發現Ninject易於啓動和運行。 Ninject有一個很酷的網站,可以幫助你入門。

我所有的項目結構首先如下:(自上而下和它的MVC)

查看 - 剃刀 視圖模型 - 我用按次1個視圖模型

ViewModelBuilder - 爲我的視圖構建我的視圖模型(用於將代碼從我的控制器中抽離出來,以便控制器保持整潔)

AutoMapper - 域實體映射到我的視圖模型

控制器 - 叫我的服務層來獲得域實體

域實體 - 我的域名

ServiceLayer(業務交涉層) - 調用我的存儲庫層以獲取域實體或這些的集合

AutoMapper再次 - 從我的第三方供應商映射自定義類型轉換成我的域實體

RepositoryLayer - 確實CRUD操作我的數據存儲

這是一個層次,但類型的域實體沿側坐並用於幾個不同的層。

注:在這篇文章中提到的一些額外的工具有:

AutoMapper - 地圖實體到其他實體 - 無需編寫映射代碼

起訂量負載 - 允許你嘲笑單元測試的東西。這在後面會提到。

現在,關於Ninject。

每層都標有接口。必須這樣做,Ninject才能對自己說。

當我發現IVehicleRepository注入一個真正的VehicleRepository,甚至注入它與FakeVehicleRepository,如果我需要一個假的。

(這涉及到你的評論 - 「這將讓我的一切綁定到一個測試XML庫」)

現在,每一層都有contstructor使Ninject(或任何其它的IOC容器)可以注入需要的東西:

public VehicleManager(IVehicleRepository vehicleRepository) 
{ 
    this._vehicleRepository = vehicleRepository; 
} 

VehicleManager位於我的serviceLayer中(不要與任何與Web服務相關的混淆)。服務層實際上就是我們所說的業務層。似乎很多人都在使用文字服務。 (儘管我認爲這很煩人,因爲它讓我想到Web服務或WCF,而不僅僅是一個業務層......無論如何......)

現在沒有進入Ninject的基本設置下面的行在我的NinjectWebCommon.cs代碼告訴ninject做什麼:

kernel.Bind<IVehicleRepository>().To<VehicleRepository>().InRequestScope(); 

這是說:

嘿ninject,當我問IVehicleRepository給我一個具體的實施VehicleRepository的。

如前所述,我可以將VehicleRepository替換爲FakeVehicleRepository,這樣我就不必從真實數據庫中讀取數據。

因此,正如你現在可以想象的那樣,每一層只依賴於接口。

我不知道你做了多少單元測試,但你也可以想象,如果你想單元測試你的服務層,並且它具有對你的存儲庫層的具體引用,那麼你將無法像你一樣進行單元測試實際上打你的存儲庫,因此從一個真正的數據庫中讀取。

記住單元測試稱爲單元測試,因爲它只測試一件事情。因此單詞UNIT。所以,因爲每個人都只知道接口,這意味着你可以在你的服務層上測試一個方法並模擬庫。

所以,如果你的服務層具有這樣的方法:

public bool ThisIsACar(int id) 
{ 
    bool isCar = false; 
    var vehicle = vehicleRepository.GetVehicleById(id); 

    if(vehicle.Type == VehicleType.Car) 
    { 
     isCar = true; 
    } 
    else 
    { 
     isCar = false; 
    } 
} 

你不會希望vehicleRepository要打電話,所以你可以起訂量是什麼VehicleRepository給你。如果它實現了一個接口,你大多隻能使用Mock的東西。

So your unit test would look like this (some pseudo code here): 
     [TestMethod] 
     public void ServiceMethodThisIsACar_Returns_True_When_VehicleIsACar() 
     { 
      // Arrange 
      _mockRepository.Setup(x => x.ThisIsACar(It.IsAny<int>)).returns(new Car with a type of VehicleType.Car) 

      // Act 
      var vehicleManager = new VehicleManager(_mockVehicleRepository.Object); 
      var vehicle = vehicleManager.ThisIsACar(3); 

      // Assert 
      Assert.IsTrue(vehicle.VehicleType == VehicleType.Car) 
     } 

因此,大家可以看到,在這一點上,這是非常簡單的,你只想要測試的IF語句在服務層,以確保結果是正確的。

你會在自己的單元測試中測試你的倉庫,如果你正在使用它,可能會模擬實體框架的工作。

所以,總的來說,我會說,使用任何IOC容器都能讓你以最少的痛苦快速運行。

我也會說,嘗試和單元測試一切,你可以。這有很多不同的原因。很明顯,它會測試你編寫的代碼,但它也會立即告訴你,如果你做了一些愚蠢的事情,比如新建一個具體的存儲庫。你會很快看到你不會有一個接口來模擬你的單元測試,這將導致你回去重構你的代碼。

我發現使用IOC,需要一段時間才能得到它。它把你的垃圾混淆直到有一天它只是點擊。在那之後,你很容易想到你如何在沒有它的情況下生活。

這裏的東西我不能生活在沒有 Automapper 起訂量 流利驗證 ReSharper的清單 - 有些恨它,我喜歡它,主要是它的單元測試UI。

無論如何,這是太長了。讓我知道你的想法。

感謝 拉斯

+0

謝謝拉斯。直到今天我纔看到這種反應。我認爲沒有人回覆,因爲我從來沒有收到通知。不知道爲什麼。我選擇了3個小時。順便說一句 - 自動映射器不再適用於SL,就像V5一樣。我不得不切換到OMU。 – 2013-02-21 19:34:26

+0

嗨託德。你是什​​麼意思你選了3個小時?你可以重新寫你的評論,因爲我不明白一半嗎?您可能需要添加新評論。對不起。 – RuSs 2013-02-22 00:17:06