Querying a database with Dapper In the current project that I am working on, we are using dapper to query the database and sometime when mapping from dynamic types to concrete types we end up with a messy block of code.

I created a folder called mappers and have created an Interface&lt;T&gt;, an abstract class inheriting from that interface and I have also set up my IOC to map according to naming conventions so that I can inject my mappers through the constructor of my query classes.

public interface IMapper&lt;out T&gt;
    {
        T Map(SqlMapper.GridReader reader);
    }

    public abstract class MapperBase&lt;T&gt; : IMapper&lt;T&gt;
    {
        public abstract T Map(SqlMapper.GridReader reader);
    }

    public class UserDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class UserDtoMapper : MapperBase&lt;UserDto&gt;
    {
        public override UserDto Map(SqlMapper.GridReader reader)
        {
            return reader.Read().Select(x =&gt; new UserDto()
            {
                Id = x.Id,
                Name = x.Name
            }).SingleOrDefault();
        }
    }

    public class QueryObject
    {
        private IMapper&lt;UserDto&gt; userDtoMapper; 

        public QueryObject(IMapper&lt;UserDto&gt; userDtoMapper)
        {
            this.userDtoMapper = userDtoMapper;
        }

        public UserDto Query(int id)
        {
            ..........
             return userDtoMapper.Map(reader)
            ...
        }
    }
Setting aside that you won't go with a Mapping framework like Jeroen Vannevel suggested in his comment, this basically looks good but can still be improved.

I don't see any value added by creating an abstract class which implements the IMapper&lt;T&gt; interface. So you better just do it like  

public class UserDtoMapper : IMapper&lt;UserDto&gt;
{
    public UserDto Map(SqlMapper.GridReader reader)
    {
        return reader.Read().Select(x =&gt; new UserDto()
        {
            Id = x.Id,
            Name = x.Name
        }).SingleOrDefault();
    }
}


But if you travel this route you should do it right and also make QueryObject class generic like  

public class QueryObject&lt;T&gt;
{
    private IMapper&lt;T&gt; mapper; 

    public QueryObject(IMapper&lt;T&gt; mapper)
    {
        this.mapper = mapper;
    }

    public T Query(int id)
    {
        ..........
         return mapper.Map(reader)
        ...
    }
}