6

考慮下面的代碼(已經簡化了)。我有一個服務類,它返回一個特定DTO對象的列表,每個對象都實現它們自己的特定接口。在實際的代碼中,由於我正在使用遺留代碼,因此迭代通過數據集來填充這些代碼。依賴注入 - 與數據傳輸對象(DTO)一起使用?

問題:

  1. 我們如何創建/使用DTO沒有newing起來或使用服務定位器反模式?在Composition Root中編寫一個空的DTO對象並通過構造函數將它注入Service類沒有多大意義,因爲實際上在填充列表時將DTO用作臨時變量。

  2. 在代碼中,您可以看到一個新的DTO示例。但是,如果我首先使DTO不實現接口,那麼這並不會讓我感覺更好。所以他們不應該實現接口,因此,不使用DI與DTOs?


public class Services : IServices 
{  
    public IList<IDTO> GetDTOs() 
    {  
     ... 
     List<IDTO> dtos = new List<IDTO>(); 
     foreach (c in d) 
     { 
      DTO dto = new DTO(); 
      dto.x = c.x; 
      dto.y = c.y; 
      dto.z = c.z; 
      dtos.Add(dto); 
     } 
     return dtos; 
    }  
} 
+0

相關:http://stackoverflow.com/questions在您的例子的情況下(我名義上是「從」類型訂單的對象進行)/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec – 2013-04-25 11:53:04

+0

重複有趣的答案:http://stackoverflow.com/questions/8135894/c-sharp- dto-constructor-and-dependency-injection/8136059#8136059 – 2013-04-25 11:55:00

回答

12

它並沒有多大意義,我使用任何DI的DTO的。我可能會使用工廠模式來爲我的模型對象獲取DTO。

DTOs不需要由容器管理它們的生命週期;我只是new他們。不要過度工程。

8

我不認爲DTO應該實現接口,因爲它們不可能實現會改變的行爲。

他們也不應該被注射。並非所有對象都應該是。我認爲這是對新的適當的調用:創建對象,使用它,讓它超出範圍並被GC'd。

1

看一看AutoMapper。我同意@duffymo,我不會使用DTO的接口。 AutoMapper是一個基於約定的對象映射器對象,它將爲您創建並填充您的DTO。如果沒有別的,它會爲你節省很多打字。我已經完成了與DTO的相關拼寫錯誤的寫作轉換例程的編寫工作。我希望能早點發現AutoMapper。

public class Services : IServices 
{  
    public IList<DTO> GetDTOs() 
    {  
     ... 
     Mapper.CreateMap<Order, DTO>(); // move map creation to startup routine 
     var dtos = new List<DTO>(); 
     foreach (c in d) 
     { 
      dtos.Add(Mapper.Map<Order, DTO>(c)); 
     } 
     return dtos; 
    } 
} 

或者使用LINQ

public class Services : IServices 
{  
    public IList<DTO> GetDTOs() 
    {  
     ... 
     Mapper.CreateMap<Order, DTO>(); // move map creation to startup routine 
     return d.Select(c => Mapper.Map<Order, DTO>(c)).ToList(); 
    } 
} 
+1

+1很好的答案。你應該使用內建的支持映射數組的AM,即你可以使用'Mapper.Map (xs)'。不確定一個IList是否是必需的b)AM支持OOTB,但如果你確實需要obv ToList會做必要的 – 2013-04-25 11:58:50