Files
PowderCoatingLogix/AUTOMAPPER_DI_FIX.md
2026-04-23 21:38:24 -04:00

162 lines
4.1 KiB
Markdown

# 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):
```csharp
// 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):
```csharp
// 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:**
1. Create the mapper instance and store it in a variable
2. Register the instance directly
3. Explicitly register it as `IMapper` interface
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:
```csharp
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
1.`src/PowderCoating.Web/Program.cs` - Lines 52-58
2.`src/PowderCoating.Api/Program.cs` - Lines 76-82
## 🧪 Testing the Fix
### In Controllers:
```csharp
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:
```csharp
[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:
```csharp
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:
1. ✅ Inject `IMapper` into any controller or service
2. ✅ Use `_mapper.Map<TDestination>(source)` without errors
3. ✅ Run the application without DI resolution errors
## 🚀 Build and Run
```bash
# 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!**