AutoMapper, ProjectTo() – Instance Version

Full source code available here.

In my previous post I showed how to use the wonderful AutoMapper ProjectTo() feature, the demo code shown worked with AutoMapper up to v8.1.1. It looked like this –

_salesContext.Products.OrderBy(p => p.ProductId).Take(count).ProjectTo<ProductModel>()

But this will not work with AutoMapper v9 and above. You will be promptly informed that No overload for the method ‘ProjectTo’ takes 0 arguments.

What happend? Well, AutoMapper moved away from a static API to an instance only API.
To get this working you need to make a few minor changes compared to previous post.
In ConfigureServices(…) replace this –

Mapper.Initialize(cfg => {
    cfg.AddProfile<MappingProfile>();
});

With this –

services.AddAutoMapper(typeof(Startup));

Then in the controller, change this

public class ProductsController : ControllerBase
{
    private readonly SalesContext _salesContext;  

    public ProductsController (SalesContext salesContext)
    {
        _salesContext = salesContext;
    }
    // snip…

To this –

 
private readonly SalesContext _salesContext;
private readonly IMapper _mapper;

public ProductsController (SalesContext salesContext, IMapper mapper)
{
    _salesContext = salesContext;
    _mapper = mapper;
}
// snip..

And finally, the ProjectTo call changes from this –

[HttpGet("projected/{count}")]
public ActionResult GetProjected(int count)
{
    return Ok(_salesContext.Products.OrderBy(p => p.ProductId).Take(count).ProjectTo<ProductModel>());
}

To this –

[HttpGet("projected/{count}")]
public ActionResult GetProjected(int count)
{
    return Ok(_mapper.ProjectTo<ProductModel>(_salesContext.Products.Take(count).OrderBy(p => p.ProductId).Take(count)));
}

The SQL produced by the instance ProjectTo() is the same as what was produced by the static version.

That’s it, easy once you figure it out.

Full source code available here.