1

這可能是以前問過的,但我正在訪問數據訪問層中的依賴Web服務,我需要問我是否應該將從該服務返回的DTO重新打包到我自己的DTO中? UI層是帶有控制器的WebAPI項目,域和數據訪問層是獨立的C#項目。在每個圖層中引用依賴性Web服務是否正確,以便dal,biz和域圖層都具有適當的代碼引用,還是應該創建我自己的DAL層中的Web服務返回的DTO視圖?域層應該直接接收依賴DTO嗎?

回答

0

從DDD的角度來看,我每次都以類似的方式做到這一點。我傾向於在傳統分層體系結構上使用Ports &適配器類型體系結構。主要是因爲它允許我通過IoC連接的接口輕鬆地引用持久層。這提供了幾乎2路參考,我不僅可以訪問我的域中的持久層,還可以在我的持久層中使用我的域模型。

我在訪問外部Web服務時所做的工作非常相似。我建立了一個新的適配器,並將接口用於訪問我的域中的外部服務,然後使用IoC進行連接。然後,我可以訪問外部Web服務,使用一些通常在我身邊(客戶端)自動生成(或手工製作)的DTO,然後將這些DTO映射到我的域對象。

例如,在一個項目中,我有,我正在做地理編碼(查找郵政編碼爲座標),一個文件夾,名爲在在我的域模型地理,我有一個名爲IGeocodingService接口:

namespace Booking.Domain.Model.Geographical 
{ 
    /// <summary> 
    /// The <see cref="IGeocodingService" /> interface. 
    /// </summary> 
    public interface IGeocodingService 
    { 
     /// <summary> 
     /// Performs a postal code query. 
     /// </summary> 
     /// <param name="countryIsoCode">The country iso code.</param> 
     /// <param name="postalCode">The postal code.</param> 
     /// <returns>A geographic coordinate.</returns> 
     Coordinate PostalCodeQuery(string countryIsoCode, string postalCode); 
    } 
} 

在一個單獨的項目叫做Booking.Adapter.CloudMade我有一個服務叫做CloudMadeGeocodingService繼承IGeocodingService

namespace Booking.Adapter.CloudMade 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Net.Http; 
    using System.Text; 
    using System.Threading.Tasks; 
    using Booking.Domain.Model.Geographical; 

    /// <summary> 
    /// The <see cref="CloudMadeAdapter" /> class. 
    /// </summary> 
    public class CloudMadeGeocodingService : IGeocodingService 
    { 
     /// <summary> 
     /// Performs a postal code query. 
     /// </summary> 
     /// <param name="countryIsoCode">The country iso code.</param> 
     /// <param name="postalCode">The postal code.</param> 
     /// <returns> 
     /// A geographic coordinate. 
     /// </returns> 
     public Coordinate PostalCodeQuery(string countryIsoCode, string postalCode) 
     { 
      string country; 

      switch (countryIsoCode) 
      { 
       case "GB": 
        country = "UK"; 
        break; 
       default: 
        country = null; 
        break; 
      } 

      if (country == null) 
      { 
       return null; 
      } 

      using (HttpClient httpClient = new HttpClient()) 
      { 
       // TODO: Make call to CloudMade v2 geocoding API. 
      } 

      // TODO: Remove this. 
      return null; 
     } 
    } 
} 

從我的域的角度來看,我有兩大好處讓我以這種方式做事。首先是服務包裝呈現爲某種外部組件,第二種是它需要並返回本機C#.NET類型或我自己的域模型類型。這個實現是隱藏的,在這種情況下,如果需要的話(本例中沒有任何DTO)以及數據來自Web API Web服務的事實也是隱藏的。

+0

謝謝。我的問題是,外部Web服務返回相當複雜的對象,而不是簡單的值,如字符串等。所以我可以選擇引用每個項目中的外部WS我可能需要使用它的數據,因此能夠引用它的DTO類型或將外部WS包裝在內部服務類(適配器,是?)中,並將它的DTO數據重新打包到我自己的DTO中。我們目前在其他地方使用AutoMapper,所以我認爲這將是重新打包Web服務數據的首選方式。主要的問題是WS不應該被引用到任何地方。 – 2014-08-29 09:41:32