依赖注入 - 与数据传输对象(DTO)一起使用?

时间:2011-06-09 18:12:51

标签: interface dependency-injection dto anti-patterns service-locator

考虑下面的代码(已经简化)。我有一个服务类,它返回一个特定DTO对象的列表,每个对象都实现自己的特定接口。在实际代码中,当我使用遗留代码时,通过迭代数据集来填充这些代码。

问题:

  1. 我们如何在不新建或使用服务定位器反模式的情况下创建/使用DTO?在Composition Root中组合一个空的DTO对象并通过构造函数将它注入Service类没有多大意义,因为我实际上在填充列表时使用DTO作为排序的临时变量。

  2. 在代码中,您可以看到我新推DTO的示例。但这感觉并不多 比我首先让DTO不实现接口更好。那么他们不应该实现接口,因此不要将DI与DTO一起使用吗?


  3. 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;
        }    
    }
    

3 个答案:

答案 0 :(得分:12)

对于我来说,对DTO使用任何DI都没有多大意义。我可能会使用工厂模式为我的模型对象获取DTO。

DTO不需要由容器管理的生命周期;我只会new他们。不要过度工程。

答案 1 :(得分:8)

我认为DTO不应该实现接口,因为它们不太可能实现会改变的行为。

他们也不应该注射。并非所有对象都应该是。我认为这是对new的适当调用:创建对象,使用它,让它超出范围并进行GC。

答案 2 :(得分:1)

看看AutoMapper。我同意@duffymo,我不会使用与DTO的接口。 AutoMapper是一个基于约定的对象对象映射器,它将为您创建和填充DTO。如果没有别的东西,它会为你节省很多打字。我一直在练习与DTO编写转换例程以及相关的拼写错误。我希望我能早点找到AutoMapper。在你的例子的情况下(我在名义上使用Order类型的“from”对象):

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();
     }
}