1
votes

Hey I'm trying to map my generic class to concrete class but using it's interface.

My service returns me data which type is

IPaggedResults<Customer>

and I want to be able to map this to

IPaggedResults<CustomerDto>

It works if I invoke mapping with:

_mapper.Map<PaggedResults<CustomerDto>>

but I want use following syntax:

_mapper.Map<IPaggedResults<CustomerDto>>

public class PaggedResults<T> : IPaggedResults<T>
{
    public IEnumerable<T> Results { get; protected set; }
    public int TotalResults { get; protected set; }
    public int TotalPages { get; protected set; }
    public int ResultsPerPage { get; protected set; }

    public PaggedResults(IEnumerable<T> results, int totalResults, int resultsPerPage)
    {
        Results = results;
        TotalResults = totalResults;
        TotalPages = totalResults / resultsPerPage;
        ResultsPerPage = resultsPerPage;
    }
}


public class CustomerDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string NIP { get; set; }
}

My mapper configuration:

        public static IMapper Initialize()
            => new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<CustomerCompany, CustomerDto>();
                cfg.CreateMap(typeof(IPaggedResults<>), typeof(PaggedResults<>));
                cfg.CreateMap(typeof(IPaggedResults<>), typeof(IPaggedResults<>)).As(typeof(PaggedResults<>));
            }).CreateMapper();

Im'using Automapper by Jimmy Bogard.

1
what is _mapper ??? - omriman12
I forgot - _mapper is IMapper instance - bielu000
But what is IMapper, it's a class you created right? put the code - omriman12
IMapper is Automapper instance which comes form Automapper library. I put mapper configuration above. - bielu000

1 Answers

0
votes

I could achieve it through the following code:

Create an extension for IMapperConfigurationExpression

public static class IMapperConfigurationExpressionExtensions 
{
    public static void MapPaggedResults<TSource, TDestination>(this IMapperConfigurationExpression exp){
        exp.CreateMap(typeof(PaggedResults<TSource>), typeof(IPaggedResults<TDestination>))
       .ConstructUsing((source, ctx) => { return ctx.Mapper.Map<PaggedResults<TDestination>>(source) as IPaggedResults<TDestination>; });
    }
}

Then use this configuration:

public static IMapper Initialize()
=> new MapperConfiguration(cfg =>
{
   cfg.CreateMap(typeof(IPaggedResults<>), typeof(PaggedResults<>));
   cfg.MapPaggedResults<CustomerCompany, CustomerDto>();
}).CreateMapper();

Then both results can be obtained:

var _mapper = Initialize();
IPaggedResults<CustomerCompany> source = new PaggedResults<CustomerCompany>(
    new List<CustomerCompany>() { new CustomerCompany() {Id =42, Name = "SomeName", NIP = "someNIP" } }, 1, 1);
var resut = _mapper.Map<PaggedResults<CustomerDto>>(source);
var resut2 = _mapper.Map<IPaggedResults<CustomerDto>>(source);