7

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

问题:

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

  2. 在代码中,您可以看到我更新 DTO 的示例。但这并不比我一开始就让 DTO 不实现接口好多少。那么他们是否应该不实现接口,从而不将 DI 与 DTO 一起使用?


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;
    }    
}
4

3 回答 3

16

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

DTO 不需要由容器管理其生命周期;我只会new他们。不要过度设计。

于 2011-06-09T18:18:40.997 回答
8

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

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

于 2011-06-09T18:19:48.183 回答
1

看看AutoMapper。我同意@duffymo,我不会使用 DTO 的接口。AutoMapper 是一个基于约定的对象到对象映射器,它将为您创建和填充您的 DTO。如果不出意外,它将为您节省大量打字。我已经完成了编写与 DTO 之间的转换例程以及相关拼写错误的练习。我希望我能早一点找到 AutoMapper。在您的示例的情况下(我名义上制作了 Order 类型的“来自”对象):

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();
     }
}
于 2011-12-21T23:54:56.667 回答