【问题标题】:Dependency Injection - use with Data Transfer Objects (DTOs)?依赖注入 - 与数据传输对象 (DTO) 一起使用?
【发布时间】:2011-09-11 22:39:10
【问题描述】:

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

问题:

  1. 我们如何创建/使用 DTO 而无需更新它们或使用服务定位器反模式?在 Composition Root 中组合一个空的 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;
    }    
}

【问题讨论】:

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • +1 好答案。不过,您应该使用 AM 对映射数组的内置支持 - 即您可以 Mapper.Map&lt;X[],X2[]&gt;(xs)。不确定 IList 是否是 a) 必要 b) AM 支持 OOTB,但如果你做了 obv ToList 会做必要的
      猜你喜欢
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多