4.1 KiB
AutoMapper Configuration Error - FIXED
🐛 Issue Found
Error: AutoMapper dependency injection not working properly - IMapper interface couldn't be resolved.
Root Cause: The mapper instance was registered, but the IMapper interface wasn't explicitly registered, causing dependency injection failures in controllers.
✅ Fix Applied
Updated both Program.cs files (Web and API) to properly register the IMapper interface.
Before (Incorrect):
// Configure AutoMapper
var mapperConfig = new MapperConfiguration(mc =>
{
mc.AddProfile<CustomerProfile>();
mc.AddProfile<JobProfile>();
});
builder.Services.AddSingleton(mapperConfig.CreateMapper());
Problem: This only registered the concrete Mapper type, not the IMapper interface that controllers depend on.
After (Correct):
// Configure AutoMapper
var mapperConfig = new MapperConfiguration(mc =>
{
mc.AddProfile<CustomerProfile>();
mc.AddProfile<JobProfile>();
});
IMapper mapper = mapperConfig.CreateMapper();
builder.Services.AddSingleton(mapper);
builder.Services.AddSingleton<IMapper>(mapper);
Solution:
- Create the mapper instance and store it in a variable
- Register the instance directly
- Explicitly register it as
IMapperinterface
This ensures that when controllers request IMapper via dependency injection, the service provider can resolve it.
📝 Why This Matters
Controllers and services use dependency injection like this:
public class CustomersController : Controller
{
private readonly IMapper _mapper; // ← Needs IMapper interface
public CustomersController(IMapper mapper)
{
_mapper = mapper;
}
}
Without the explicit IMapper registration, the DI container can't resolve this dependency, causing runtime errors:
InvalidOperationException: Unable to resolve service for type 'AutoMapper.IMapper'
🎯 Files Modified
- ✅
src/PowderCoating.Web/Program.cs- Lines 52-58 - ✅
src/PowderCoating.Api/Program.cs- Lines 76-82
🧪 Testing the Fix
In Controllers:
public class CustomersController : Controller
{
private readonly IMapper _mapper;
public CustomersController(IMapper mapper)
{
_mapper = mapper; // ✅ Now works!
}
public async Task<IActionResult> Index()
{
var customers = await _unitOfWork.Customers.GetAllAsync();
var dtos = _mapper.Map<List<CustomerDto>>(customers); // ✅ Works!
return View(dtos);
}
}
In API Controllers:
[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
private readonly IMapper _mapper;
public CustomersController(IMapper mapper)
{
_mapper = mapper; // ✅ Now works!
}
[HttpGet]
public async Task<ActionResult<List<CustomerDto>>> GetAll()
{
var customers = await _unitOfWork.Customers.GetAllAsync();
return Ok(_mapper.Map<List<CustomerDto>>(customers)); // ✅ Works!
}
}
💡 Alternative Approach (For Reference)
If you were using AutoMapper.Extensions.Microsoft.DependencyInjection, you could do:
builder.Services.AddAutoMapper(typeof(CustomerProfile).Assembly);
But since we're using AutoMapper 16.0 without the Extensions package, we need the manual configuration shown above.
✅ Verification
After this fix, you should be able to:
- ✅ Inject
IMapperinto any controller or service - ✅ Use
_mapper.Map<TDestination>(source)without errors - ✅ Run the application without DI resolution errors
🚀 Build and Run
# Clean and rebuild
dotnet clean
dotnet build
# Expected: Build succeeded. 0 Warning(s) 0 Error(s)
# Run the application
cd src/PowderCoating.Web
dotnet run
# Should start without errors
📋 Summary
What was wrong: Mapper instance created but IMapper interface not registered
What we fixed: Explicitly registered both the instance and the IMapper interface
Result: Dependency injection now works correctly in all controllers and services
AutoMapper configuration is now correct and ready to use! ✅