Initial commit
This commit is contained in:
@@ -0,0 +1,369 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user