370 lines
9.8 KiB
Markdown
370 lines
9.8 KiB
Markdown
# Final Update Summary - AutoMapper 16.0 Without Extensions
|
|
|
|
## ✅ All Changes Completed
|
|
|
|
### 1. **Removed AutoMapper.Extensions.Microsoft.DependencyInjection**
|
|
- Replaced with direct **AutoMapper 16.0** package
|
|
- Manual configuration using `MapperConfiguration`
|
|
- Singleton registration for better performance
|
|
|
|
### 2. **All Projects Reverted to .NET 8.0 LTS**
|
|
- ✅ PowderCoating.Core → net8.0
|
|
- ✅ PowderCoating.Application → net8.0
|
|
- ✅ PowderCoating.Infrastructure → net8.0
|
|
- ✅ PowderCoating.Web → net8.0
|
|
- ✅ PowderCoating.Api → net8.0
|
|
- ✅ PowderCoating.Shared → net8.0
|
|
- ✅ PowderCoating.UnitTests → net8.0
|
|
- ✅ PowderCoating.IntegrationTests → net8.0
|
|
|
|
### 3. **AutoMapper Configuration**
|
|
|
|
#### Web Project (`PowderCoating.Web/Program.cs`)
|
|
```csharp
|
|
using AutoMapper;
|
|
using PowderCoating.Application.Mappings;
|
|
|
|
// Configure AutoMapper
|
|
var mapperConfig = new MapperConfiguration(mc =>
|
|
{
|
|
mc.AddProfile<CustomerProfile>();
|
|
mc.AddProfile<JobProfile>();
|
|
});
|
|
builder.Services.AddSingleton(mapperConfig.CreateMapper());
|
|
```
|
|
|
|
#### API Project (`PowderCoating.Api/Program.cs`)
|
|
```csharp
|
|
using AutoMapper;
|
|
using PowderCoating.Application.Mappings;
|
|
|
|
// Configure AutoMapper
|
|
var mapperConfig = new MapperConfiguration(mc =>
|
|
{
|
|
mc.AddProfile<CustomerProfile>();
|
|
mc.AddProfile<JobProfile>();
|
|
});
|
|
builder.Services.AddSingleton(mapperConfig.CreateMapper());
|
|
```
|
|
|
|
### 4. **AutoMapper Profiles Created**
|
|
|
|
#### CustomerProfile.cs
|
|
**Location:** `src/PowderCoating.Application/Mappings/CustomerProfile.cs`
|
|
|
|
Maps:
|
|
- Customer ↔ CustomerDto
|
|
- CreateCustomerDto → Customer
|
|
- UpdateCustomerDto → Customer
|
|
- Customer → CustomerListDto (with contact name formatting)
|
|
|
|
#### JobProfile.cs
|
|
**Location:** `src/PowderCoating.Application/Mappings/JobProfile.cs`
|
|
|
|
Maps:
|
|
- Job ↔ JobDto
|
|
- CreateJobDto → Job
|
|
- UpdateJobDto → Job
|
|
- Job → JobListDto
|
|
- JobItem ↔ JobItemDto
|
|
- CreateJobItemDto → JobItem
|
|
- Job → ShopFloorJobDto (with priority colors & next steps)
|
|
|
|
**Smart Features:**
|
|
- Priority color coding (Rush=danger, Urgent=warning, etc.)
|
|
- Next step suggestions based on job status
|
|
- Enum name formatting ("InPreparation" → "In Preparation")
|
|
|
|
### 5. **Package Updates**
|
|
|
|
All packages updated to stable .NET 8.0 versions:
|
|
|
|
| Package | Version |
|
|
|---------|---------|
|
|
| AutoMapper | 16.0.0 |
|
|
| Microsoft.AspNetCore.Identity.UI | 8.0.0 |
|
|
| Microsoft.EntityFrameworkCore | 8.0.0 |
|
|
| Microsoft.EntityFrameworkCore.SqlServer | 8.0.0 |
|
|
| Microsoft.EntityFrameworkCore.Design | 8.0.0 |
|
|
| Microsoft.AspNetCore.Authentication.JwtBearer | 8.0.0 |
|
|
| Swashbuckle.AspNetCore | 6.5.0 |
|
|
| Serilog.AspNetCore | 8.0.0 |
|
|
| FluentValidation | 11.9.0 |
|
|
| Microsoft.SemanticKernel | 1.0.1 |
|
|
| Microsoft.ML | 3.0.1 |
|
|
|
|
## 📦 What's Changed from Previous Version
|
|
|
|
### Before:
|
|
```csharp
|
|
// Used extension package
|
|
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
|
|
```
|
|
|
|
### After:
|
|
```csharp
|
|
// Manual configuration with explicit profile registration
|
|
var mapperConfig = new MapperConfiguration(mc =>
|
|
{
|
|
mc.AddProfile<CustomerProfile>();
|
|
mc.AddProfile<JobProfile>();
|
|
});
|
|
builder.Services.AddSingleton(mapperConfig.CreateMapper());
|
|
```
|
|
|
|
## 🎯 Benefits of This Approach
|
|
|
|
### 1. **No Extension Package Dependency**
|
|
- Direct AutoMapper 16.0 reference only
|
|
- Simpler dependency tree
|
|
- Better control over configuration
|
|
|
|
### 2. **Explicit Profile Registration**
|
|
- Know exactly which profiles are registered
|
|
- Easier to debug
|
|
- Better IntelliSense support
|
|
|
|
### 3. **Singleton Registration**
|
|
- Better performance (mapper created once)
|
|
- Thread-safe
|
|
- Recommended by AutoMapper team
|
|
|
|
### 4. **Compile-Time Safety**
|
|
- Errors caught at compile time
|
|
- No runtime profile discovery issues
|
|
- Clear configuration errors
|
|
|
|
## 🚀 How to Add New Profiles
|
|
|
|
When you add new features, follow this pattern:
|
|
|
|
### Step 1: Create Profile Class
|
|
Create in `src/PowderCoating.Application/Mappings/`:
|
|
|
|
```csharp
|
|
using AutoMapper;
|
|
using PowderCoating.Core.Entities;
|
|
using PowderCoating.Application.DTOs.YourModule;
|
|
|
|
namespace PowderCoating.Application.Mappings;
|
|
|
|
public class YourModuleProfile : Profile
|
|
{
|
|
public YourModuleProfile()
|
|
{
|
|
CreateMap<YourEntity, YourDto>();
|
|
CreateMap<CreateYourDto, YourEntity>();
|
|
// Add more mappings...
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 2: Register in Both Program.cs Files
|
|
|
|
**In Web/Program.cs:**
|
|
```csharp
|
|
var mapperConfig = new MapperConfiguration(mc =>
|
|
{
|
|
mc.AddProfile<CustomerProfile>();
|
|
mc.AddProfile<JobProfile>();
|
|
mc.AddProfile<YourModuleProfile>(); // ← Add this line
|
|
});
|
|
```
|
|
|
|
**In Api/Program.cs:**
|
|
```csharp
|
|
var mapperConfig = new MapperConfiguration(mc =>
|
|
{
|
|
mc.AddProfile<CustomerProfile>();
|
|
mc.AddProfile<JobProfile>();
|
|
mc.AddProfile<YourModuleProfile>(); // ← Add this line
|
|
});
|
|
```
|
|
|
|
## 🔍 Verification Steps
|
|
|
|
### 1. Extract the Archive
|
|
```bash
|
|
# Windows
|
|
Expand-Archive PowderCoatingApp.zip -DestinationPath C:\Projects\
|
|
|
|
# Mac/Linux
|
|
tar -xzf PowderCoatingApp.tar.gz -C ~/Projects/
|
|
```
|
|
|
|
### 2. Restore Packages
|
|
```bash
|
|
cd PowderCoatingApp
|
|
dotnet restore
|
|
```
|
|
|
|
**Expected Output:**
|
|
```
|
|
Restore succeeded.
|
|
```
|
|
|
|
### 3. Build the Solution
|
|
```bash
|
|
dotnet build
|
|
```
|
|
|
|
**Expected Output:**
|
|
```
|
|
Build succeeded.
|
|
0 Warning(s)
|
|
0 Error(s)
|
|
```
|
|
|
|
### 4. Verify AutoMapper Configuration
|
|
When you run the application, AutoMapper will validate all mappings at startup. Any configuration errors will be caught immediately.
|
|
|
|
## 📝 Usage Examples
|
|
|
|
### In Controllers
|
|
```csharp
|
|
public class CustomersController : Controller
|
|
{
|
|
private readonly IUnitOfWork _unitOfWork;
|
|
private readonly IMapper _mapper;
|
|
|
|
public CustomersController(IUnitOfWork unitOfWork, IMapper mapper)
|
|
{
|
|
_unitOfWork = unitOfWork;
|
|
_mapper = mapper;
|
|
}
|
|
|
|
public async Task<IActionResult> Index()
|
|
{
|
|
var customers = await _unitOfWork.Customers.GetAllAsync();
|
|
var customerDtos = _mapper.Map<List<CustomerListDto>>(customers);
|
|
return View(customerDtos);
|
|
}
|
|
}
|
|
```
|
|
|
|
### In API Controllers
|
|
```csharp
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class JobsController : ControllerBase
|
|
{
|
|
private readonly IMapper _mapper;
|
|
|
|
public JobsController(IMapper mapper)
|
|
{
|
|
_mapper = mapper;
|
|
}
|
|
|
|
[HttpGet]
|
|
public async Task<ActionResult<List<JobListDto>>> GetAll()
|
|
{
|
|
var jobs = await _unitOfWork.Jobs.GetAllAsync();
|
|
return Ok(_mapper.Map<List<JobListDto>>(jobs));
|
|
}
|
|
}
|
|
```
|
|
|
|
## ⚠️ Important Notes
|
|
|
|
### AutoMapper Validation
|
|
AutoMapper validates configurations at startup. If you see an error like:
|
|
```
|
|
AutoMapper.AutoMapperConfigurationException: Unmapped members were found.
|
|
```
|
|
|
|
This means a mapping is incomplete. Check:
|
|
1. All DTOs have corresponding mappings
|
|
2. Property names match or are explicitly mapped
|
|
3. Complex mappings have custom resolvers
|
|
|
|
### Adding Collections
|
|
When mapping collections, AutoMapper handles it automatically:
|
|
```csharp
|
|
var customers = await _unitOfWork.Customers.GetAllAsync();
|
|
var dtos = _mapper.Map<List<CustomerDto>>(customers); // Works automatically
|
|
```
|
|
|
|
### Nested Mappings
|
|
AutoMapper automatically maps nested objects if they have profiles:
|
|
```csharp
|
|
// If Job has Customer property and both have profiles, this works:
|
|
var jobDto = _mapper.Map<JobDto>(job); // Automatically maps job.Customer
|
|
```
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Error: "Type 'CustomerProfile' not found"
|
|
**Solution:** Add using statement:
|
|
```csharp
|
|
using PowderCoating.Application.Mappings;
|
|
```
|
|
|
|
### Error: "No parameterless constructor defined"
|
|
**Solution:** Ensure profile classes have no constructor parameters:
|
|
```csharp
|
|
public class CustomerProfile : Profile
|
|
{
|
|
public CustomerProfile() // ← Must be parameterless
|
|
{
|
|
// Configuration...
|
|
}
|
|
}
|
|
```
|
|
|
|
### Build Error: Package version conflicts
|
|
**Solution:** Clean and restore:
|
|
```bash
|
|
dotnet clean
|
|
dotnet nuget locals all --clear
|
|
dotnet restore
|
|
dotnet build
|
|
```
|
|
|
|
## 📋 File Changes Summary
|
|
|
|
### Modified Files:
|
|
1. **src/PowderCoating.Web/PowderCoating.Web.csproj** - Package updates
|
|
2. **src/PowderCoating.Web/Program.cs** - Manual AutoMapper config
|
|
3. **src/PowderCoating.Api/PowderCoating.Api.csproj** - Package updates
|
|
4. **src/PowderCoating.Api/Program.cs** - Manual AutoMapper config
|
|
5. **src/PowderCoating.Core/PowderCoating.Core.csproj** - .NET 8.0
|
|
6. **src/PowderCoating.Application/PowderCoating.Application.csproj** - .NET 8.0, AutoMapper 16.0
|
|
7. **src/PowderCoating.Infrastructure/PowderCoating.Infrastructure.csproj** - .NET 8.0
|
|
8. **src/PowderCoating.Shared/PowderCoating.Shared.csproj** - .NET 8.0
|
|
9. **tests/PowderCoating.UnitTests/PowderCoating.UnitTests.csproj** - .NET 8.0
|
|
10. **tests/PowderCoating.IntegrationTests/PowderCoating.IntegrationTests.csproj** - .NET 8.0
|
|
|
|
### New Files:
|
|
1. **src/PowderCoating.Application/Mappings/CustomerProfile.cs**
|
|
2. **src/PowderCoating.Application/Mappings/JobProfile.cs**
|
|
|
|
## ✨ Key Improvements
|
|
|
|
✅ **Cleaner Dependencies** - No Extensions package needed
|
|
✅ **Explicit Configuration** - Clear what's registered
|
|
✅ **Better Performance** - Singleton mapper instance
|
|
✅ **Type Safety** - Compile-time profile validation
|
|
✅ **Easier Debugging** - Clear error messages
|
|
✅ **.NET 8.0 LTS** - Long-term support until 2026
|
|
✅ **AutoMapper 16.0** - Latest features and performance
|
|
|
|
## 🎉 Ready to Use!
|
|
|
|
Your project now has:
|
|
- ✅ AutoMapper 16.0 without Extensions package
|
|
- ✅ Manual configuration for full control
|
|
- ✅ All projects on .NET 8.0 LTS
|
|
- ✅ Complete mapping profiles for Customer and Job modules
|
|
- ✅ Smart features (priority colors, next steps, formatting)
|
|
|
|
**Download, extract, and build - it's ready to go!**
|
|
|
|
When you add new features, just:
|
|
1. Create a new Profile class
|
|
2. Add it to MapperConfiguration in both Program.cs files
|
|
3. That's it!
|
|
|
|
---
|
|
|
|
**Note:** When .NET 10.0 releases in November 2025, you can upgrade by simply changing `<TargetFramework>net8.0</TargetFramework>` to `net10.0` in all .csproj files and updating package versions.
|