Dependency Injection - use with Data Transfer Objects (DTOs)?

寵の児 提交于 2019-12-17 20:11:06

问题


Consider the code below (which has been simplified). I have a service class that returns a list of specific DTO objects that each implement their own specific interface. In the actual code these are getting populated by iterating thru a Dataset as I'm working with legacy code.

Questions:

  1. How do we create/use a DTO without newing them up or using the Service Locator anti-pattern? It doesn't make much sense to compose an empty DTO object in the Composition Root and inject it into the Service class via the constructor, because I'd actually be using the DTO as a temporary variable of sorts while populating a list.

  2. In the code you can see an example of me newing up the DTO. But this doesn't feel much better than if I made the DTOs not implement interfaces in the first place. So should they not implement interfaces then and thus, not use DI with DTOs?


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

回答1:


it doesn't make much sense to me to use any DI for DTOs. I would probably use the Factory Pattern to get DTOs for my model objects.

DTOs don't need their life cycle managed by the container; I would just new them. Dont over-engineer.




回答2:


I don't think DTOs should implement interfaces, because they aren't likely to implement behavior that will change.

They also shouldn't be injected. Not all objects should be. I think this is an appropriate call to new: create the object, use it, let it go out of scope and be GC'd.




回答3:


Have a look at AutoMapper. And I agree with @duffymo, I wouldn't use interfaces with DTO's. AutoMapper is a convention-based object to object mapper that will create and populate your DTO's for you. If nothing else it will save you a lot of typing. I've been through the exercise of writing conversion routines to/from DTO's with associated typos. I wish I had found AutoMapper a bit sooner. In the case of your example (where I've nominally made the "from" object of type 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;
     }
}

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


来源:https://stackoverflow.com/questions/6297322/dependency-injection-use-with-data-transfer-objects-dtos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!