1

When playing around with AutoMapper I was wondering whether the following is possible to implement like this (haven't been able to set it up correctly).

Base Service:

public class BaseService<T, IEntityDTO> : IService<T, IEntityDTO> where T : class, IEntity
{
    private IUnitOfWork _unitOfWork;
    private IRepository<IEntity> _repository;
    private IMapper _mapper;

    public BaseService(IUnitOfWork unitOfWork, IMapper mapper)
    {
        _unitOfWork = unitOfWork;
        _repository = unitOfWork.Repository<IEntity>();
        _mapper = mapper;
    }

    public IList<IEntityDTO> GetAll()
    {
        return _mapper.Map<IList<IEntityDTO>>(_repository.GetAll().ToList());
    }
}

Concrete Service:

public class HotelService : BaseService<Hotels, HotelsDTO>, IHotelService
{

    private IUnitOfWork _unitOfWork;
    private IRepository<Hotels> _hotelsRepository;
    private IMapper _mapper;

    public HotelService(IUnitOfWork unitOfWork, IMapper mapper) : base(unitOfWork, mapper)
    {
        _unitOfWork = unitOfWork;
        _hotelsRepository = unitOfWork.Repository<Hotels>();
        _mapper = mapper;
    }
}

Current mappings:

public class AutoMapperProfileConfiguration : Profile
{
    protected override void Configure()
    {
        CreateMap<Hotels, HotelsDTO>().ReverseMap();
    }
}

I'm kindly clueless on how the mapping should be done. Anyone any advice or is this just not the way to go?

user2963570
  • 381
  • 6
  • 21
  • It's unclear what you're asking. What exactly are you having trouble with? – Thomas Levesque Sep 13 '16 at 09:11
  • I updated the code to make it clear. I'm trying to implement generic mappings where i'm able to, based on whats getting passed to my base service, do mappings of my concrete types. – user2963570 Sep 13 '16 at 09:15
  • I want to write something generic for all my concrete services so the mappings go automagically. Otherwise i'm forced to drop the getall method to my concrete services. So i have to handle the mappings on a concrete way. For example: _mapper.Map>(_repository.GetAll().ToList()); – user2963570 Sep 13 '16 at 09:17

2 Answers2

2

You can specify DTO type in BaseService as generic parameter:

public class BaseService<T, TDTO> : IService<T, TDTO> 
    where T : class, IEntity
    where TDTO : class, IEntityDTO
{
    private IRepository<T> _repository;
...
...
    public IList<TDTO> GetAll()
    {
        return _mapper.Map<IList<TDTO>>(_repository.GetAll().ToList());
    }
}
Aleksey L.
  • 35,047
  • 10
  • 74
  • 84
  • Thanks for your reply but this doesn't change the case. The problem is Automapper tries to map the IEntity which i'm trying to avoid. I want the mapping done from Hotel to HotelDTO and not from IEntity to IEntityDTO. I want to use IEntity and IEntityDTO as placeholders for my concrete types so the mapping can be done in the generic base service. – user2963570 Sep 13 '16 at 09:32
  • just use concrete types instead of interfaces (`IRepository ` and `Map>`) – Aleksey L. Sep 13 '16 at 11:06
  • what's the point of generics if you want to work with interfaces? – Aleksey L. Sep 13 '16 at 11:50
  • You were right about the generics. I miss understood what you meant. – user2963570 Sep 14 '16 at 07:19
0

Managed to solve my problem with the following line of code which looks up the mapping of the passed entity to the basecontroller.

public List<TDTO> GetAll()
{
    var list = _repository.GetAll().ToList();
    return (List<TDTO>)_mapper.Map(list, list.GetType(), typeof(IList<TDTO>));
}
user2963570
  • 381
  • 6
  • 21