Reputation: 579
I'm using AutoMapper 7.0.1 and AutoMapper.Extensions.Microsoft.DependencyInjection 5.0.1 in my ASP.NET Core 2.1 web application. When I map to a type that isn't configured with ConstructUsingServiceLocator()
, the mapping works. When I map to a type that is configured with ConstructUsingServiceLocator()
, it throws the following:
AutoMapperMappingException: Cannot create an instance of type
AutoMapperTest.Destination
AutoMapper.MappingOperationOptions<TSource, TDestination>.CreateInstance<T>() in MappingOperationOptions.cs, line 47
I'm following the latest guidance for using AutoMapper with ASP.NET Core given here: How to pass a service from .net core di container to a new object created with automapper
I've reproduced this with a minimal example in a brand new project. Here's the relevant parts:
New project > APS.NET Core Web Application > Web Application
Install AutoMapper 7.0.1 and AutoMapper.Extensions.Microsoft.DependencyInjection 5.0.1 Nuget packages.
Source:
public class Source
{
public string Name { get; set; }
}
Destination:
public class Destination
{
private readonly IDestinationRepository _repo;
public Destination(IDestinationRepository repo)
{
_repo = repo ?? throw new ArgumentNullException(nameof(repo));
}
public string Name { get; set; }
}
IDestinationRepository:
public interface IDestinationRepository
{
}
DestinationRepository:
public class DestinationRepository : IDestinationRepository
{
}
MappingProfile:
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Source, Destination>().ConstructUsingServiceLocator();
}
}
Startup.ConfigureServices(IServiceCollection services):
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IDestinationRepository, DestinationRepository>();
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAutoMapper();
}
IndexModel:
public class IndexModel : PageModel
{
private readonly IMapper _mapper;
public IndexModel(IMapper mapper)
{
_mapper = mapper;
}
public void OnGet()
{
_mapper.ConfigurationProvider.AssertConfigurationIsValid(); // <- Succeeds
var repo = _mapper.ServiceCtor.Invoke(typeof(IDestinationRepository)); // <- repo is non-null
var source = new Source {Name = "Test"};
var destination = _mapper.Map<Source, Destination>(source); // <- Fails!!
}
}
The above fails on the _mapper.Map<Source, Destination>(source)
call with the exception listed above. I've verified MappingProfile
is getting loaded.
If I change the Destination
ctor to be parameterless, it still fails.
However, if I remove ConstructUsingServiceLocator()
from MappingProfile
(with the empty Destination
ctor), my mapping starts to work.
What am I doing wrong here? Thanks for any help!
Upvotes: 3
Views: 1339
Reputation: 5814
Your Destination
class is not registered in di container and so it's not possible to let di container create a new instance of class Destination
.
Upvotes: 4