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

7
考虑下面的代码(已经简化)。我有一个服务类,它返回一个特定DTO对象列表,每个对象都实现自己的特定接口。在实际代码中,这些通过迭代数据集进行填充,因为我正在使用遗留代码。
问题:
1. 如何在不newing它们或使用Service Locator反模式的情况下创建/使用DTO? 在组合根中构成一个空的DTO对象并通过构造函数将其注入到服务类中并不太有意义,因为我实际上将使用DTO作为一种临时变量来填充列表。
2. 在代码中可以看到我newing DTO的示例。但这并不比如果我一开始就没有使DTO实现接口更好。那么它们不应该实现接口,因此不使用DTO的DI?
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;
    }    
}

相关:https://dev59.com/4m445IYBdhLWcg3we6V9 - Ruben Bartelink
重复但有趣的答案:https://dev59.com/Zmsz5IYBdhLWcg3wDzwA#8136059 - Ruben Bartelink
3个回答

16

对于DTO(数据传输对象),我认为使用任何依赖注入(DI)并没有什么意义。相反,我会使用工厂模式来获取我的模型对象的DTO。

DTO不需要容器来管理其生命周期;我只需使用new关键字创建它们即可。不要过度设计。


8

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

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


1

看一下AutoMapper。我同意@duffymo的观点,我不会在DTO中使用接口。AutoMapper是一个基于约定的对象映射器,它将为您创建和填充DTO。如果没有其他问题,它将为您节省大量打字时间。我曾经写过与DTO相关的转换程序,并出现了相关的拼写错误。我希望我早点发现AutoMapper。在您的示例中(我将“from”对象名义上设置为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();
     }
}

1
+1 很好的回答。不过你应该使用 AM 内置的数组映射支持 - 也就是说,你可以使用 Mapper.Map<X[],X2[]>(xs)。不确定 IList 是否必要或者是否被 AM 支持 OOTB,但如果你确实需要,ToList 就会完成必要的工作。 - Ruben Bartelink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接