The system follows a microservices architecture with clear separation of concerns:
1. EGU.PartnerPortal.Web - Blazor WebAssembly frontend
2. EGU.PartnerPortal.ApiService - Core business API
3. EGU.PartnerPortal.IntegrationServiceAPI - External system integration
4. EGU.PartnerPortal.AppHost - .NET Aspire orchestration
5. EGU.PartnerPortal.Shared - Common utilities and DTOs
6. EGU.PartnerPortal.ServiceDefaults - Shared service configurations
Service-Oriented Architecture
┌─────────────────┐
│ Presentation │ ← Blazor Components, Pages
├─────────────────┤
│ Application │ ← Controllers, API Services
├─────────────────┤
│ Business │ ← Validation, Mapping, Domain Logic
├─────────────────┤
│ Data Access │ ← Entity Framework, DbContext
├─────────────────┤
│ Integration │ ← External API Services, SOAP
└─────────────────┘
// Service Registration Example (Program.cs)
builder.Services.AddScoped<IWorkOrderApiService, WorkOrderApiService>();
builder.Services.AddScoped<IWorkOrderValidationService, WorkOrderValidationService>();
builder.Services.AddScoped<IWorkOrderMapperService, WorkOrderMapperService>();
Services/
├── WorkOrder/
│ ├── ApiServices/
│ │ ├── WorkOrderApiService.cs
│ │ └── Interfaces/
│ │ └── IWorkOrderApiService.cs
│ ├── ValidationServices/
│ │ ├── WorkOrderValidationService.cs
│ │ └── Interfaces/
│ │ └── IWorkOrderValidationService.cs
│ └── MapperServices/
│ ├── WorkOrderMapperService.cs
│ └── Interfaces/
│ └── IWorkOrderMapperService.cs
public class WorkOrderApiService : IWorkOrderApiService
{
private readonly DatabaseContext _dbContext;
private readonly IWorkOrderValidationService _workOrderValidationService;
private readonly IWorkOrderMapperService _workOrderMapperService;
private readonly IHttpClientFactory _httpClientFactory;
public WorkOrderApiService(
DatabaseContext dbContext,
IWorkOrderValidationService workOrderValidationService,
IWorkOrderMapperService workOrderMapperService,
IHttpClientFactory httpClientFactory)
{
_dbContext = dbContext;
_workOrderValidationService = workOrderValidationService;
_workOrderMapperService = workOrderMapperService;
_httpClientFactory = httpClientFactory;
}
}
All service methods must be asynchronous:
// ✅ Good - Consistent async pattern
public async Task<WorkOrderFormResponse?> CreateWorkOrder(WorkOrderCreateRequest request)
{
await _workOrderValidationService.ValidateRegistrationRequest(request.RegistrationCreateRequest);
var workOrder = await _workOrderMapperService.MapperWorkOrder(request.RegistrationCreateRequest);
_dbContext.WorkOrder.Add(workOrder);
await _dbContext.SaveChangesAsync();
return await GetWorkOrderForm(workOrder.ID);
}
// ❌ Bad - Mixing sync and async
public WorkOrderFormResponse CreateWorkOrder(WorkOrderCreateRequest request)
{
var result = ValidateRegistrationRequest(request.RegistrationCreateRequest).Result;
// Causes deadlocks and blocking
}