2012-11-19 69 views
1

我使用實體框架5代碼首先,的WebAPI,ASPNET MVC 4,庫和工作模式的單位已經等工程。的WebAPI ASPNET 4架構

我的體系結構如下:

  • 一項目與上下文,倉庫,單位工作POCOS
  • 一個項目,等
  • 與合同(IRepository,IUnitOfWork等)
  • 一個項目
  • 持有APIC一個項目的WebAPI模型的每個實體的控制器(GET,POST,PUT,DELETE)。

現在,如果我不想使用SPA(因爲我現在沒有時間去學習它),並且我想快速做些什麼,我該怎麼做?一個新的ASPNET MVC 4項目,控制器繼承自Controller而不是ApiController,以及那些使用WebApi控制器的控制器?

是否這樣?

public ActionResult Index() 
{ 
    return View(WebApiProj.Uow.Houses.GetAll()); 
} 

這似乎不是很好,因爲它應該創建一個Get指向另一個項目中的WebApi控制器。

我在考慮這個架構,因爲移動客戶端,Web客戶端和任何其他客戶端都會調用聽起來不錯的相同服務。

此架構上的任何建議?優點還是缺點?

回答

2

我不確定您展示的內容是否可能? WebApiProj.Uow.Houses.GetAll()對待房屋,就好像它是一個帶有GetAll函數的類。 Houses是一個實例類,需要根據請求實例化,並且可能/應該有構造函數注入問題來處理... GetAll通常是實例方法。

鑑於您處於一種情況下,您將擁有多個代碼客戶端,即WebApi控制器和MVC控制器,您應該考慮在項目中添加服務層。 http://martinfowler.com/eaaCatalog/serviceLayer.html

您的服務層可能會採用單個類的形式(如果這是一個小型的ish項目,但如果需要將其拆分),它將會注入存儲庫和基礎架構代碼。您最終應該得到一系列包含存儲庫,工廠和工作單元類別之間的編排邏輯的CRUD和UseCase探測方法名稱。然後

public interface IMyServiceLayerClass 
{ 
     IEnumerable<House> GetAllHouses(); 
     House SaveHouse(House house); 
     IEnumerable<Windows> GetAllHouseWindows(int houseId); 
     //etc 
} 

public class MyServiceLayerClass : IMyServiceLayerClass 
{ 
    private readonly IRepository<House> _houseRepository; 
    private readonly IUnitOfWork _unitOfWork; 
    private readonly IRepositoryTypeB _repositoryTypeB; 

    Public MyServiceLayerClass(IUnitOfWork unitofwork, IRepository<House> houseRepository, IRepositoryTypeB repositoryTypeB) 
    { 
      //Populate the private readonly's 
    } 

    public IEnumerable<House> GetAllHouses() 
    { 
     return _houseRepository.GetAll(); 
    } 

你兩種控制器可以接受服務類,並具有非常薄的邏輯只是轉發到服務層。

public class HomeController : Controller 
{ 
    private readonly IMyServiceLayerClass _myServiceLayerClass; 

    public HomeController(IMyServiceLayerClass myServiceLayerClass) 
    { 
     _myServiceLayerClass= myServiceLayerClass; 
    } 

    public ViewResult Index() 
    { 
     return View(_myServiceLayerClass.GetAllHouses()); 
    } 

相同的API:

public class HouseController : ApiController 
{ 
    private readonly IMyServiceLayerClass _myServiceLayerClass; 

    public HouseController (IMyServiceLayerClass myServiceLayerClass) 
    { 
     _myServiceLayerClass= myServiceLayerClass; 
    } 

    public IEnumerable<House> Get() 
    { 
     return _myServiceLayerClass.GetAllHouses(); 
    } 

這將允許你重用跨抽象邏輯遠離你的WebAPI和MVC應用程序控制器相同的業務邏輯和業務流程。

此代碼可以很容易地存在於定義合同的項目中,因爲它僅依賴於接口。或者您也可以將其接口添加到合同中,然後創建另一個可以保存服務類實現的項目類Domain或Service。

我強烈建議你讓你的控制器做他們最擅長的事情,讓他們處理UI特定元素的委託,並將非UI特定的邏輯重新分解爲可重用的服務層。這將允許控制器的單元測試專注於測試正確的操作結果和狀態代碼等,並允許您的域邏輯進行獨立測試。

+1

這就是我想要完成的,我沒有得到的是:ApiControllers不會是服務層嗎?他們有CRUD操作。我的意思是,服務層和ApiControllers之間有什麼區別? 感謝您的回答! – polonskyg

+0

排序,是的!從某種意義上說,它們只允許你訪問特定於控制器的方法,例如一個控制器的房屋將是一個「類」服務類的房屋,但添加門等等和他們的新控制器,那麼你也需要轉發到這些控制器......一個服務類可以抽象出你的整個領域房屋,門和Windows等... –

+0

我已經添加了有關GetAll不是靜態的註釋,以及您的方法是否可行。還增加了一個備註:親們的服務類和單元測試 –

1

看看my answer for another architecture question on MVC。您的問題的關鍵是具有MVC控制器和Web API控制器可用於訪問業務模型(MVC中的M)的應用程序或域層。您不希望直接從MVC控制器調用Web API,因爲它具有此處不需要的序列化和反序列化開銷。而是直接調用應用程序/域圖層。

+0

良好的繪畫,我喜歡它,類似於馬克的回答。謝謝! – polonskyg