162 lines
4.1 KiB
Markdown
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!** ✅
|