依赖注入 - 与数据传输对象 (DTO) 一起使用?
Posted
技术标签:
【中文标题】依赖注入 - 与数据传输对象 (DTO) 一起使用?【英文标题】:Dependency Injection - use with Data Transfer Objects (DTOs)? 【发布时间】:2011-09-11 22:39:10 【问题描述】:考虑下面的代码(已被简化)。我有一个服务类,它返回一个特定 DTO 对象的列表,每个对象都实现自己的特定接口。在实际代码中,当我使用遗留代码时,这些是通过迭代数据集来填充的。
问题:
我们如何创建/使用 DTO 而无需更新它们或使用服务定位器反模式?在 Composition Root 中组合一个空的 DTO 对象并通过构造函数将其注入到 Service 类中没有多大意义,因为我实际上在填充列表时会将 DTO 用作各种临时变量。
在代码中,您可以看到我更新 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;
【问题讨论】:
相关:***.com/questions/4835046/… 复制有趣的答案:***.com/questions/8135894/… 【参考方案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<X[],X2[]>(xs)
。不确定 IList 是否是 a) 必要 b) AM 支持 OOTB,但如果你做了 obv ToList 会做必要的以上是关于依赖注入 - 与数据传输对象 (DTO) 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章