Official Reference Implementation

AUA Framework Architecture Guide

A complete end-to-end reference guide covering domain entities, EF Core configurations, DTO mapping strategies, data encapsulation, business services, and web API controllers in AUA Framework.

Phase 1

Domain Entities & Auditing Infrastructure

Student.cs

All domain entities inherit from DomainEntity or BaseDomainEntity with optional support for automated lifecycle auditing interfaces.

// Domain Entity with Primary Key, Creation Audit, and Soft Delete Audit
public class Student : DomainEntity<long>, ICreationAudited, IDeletionAudited
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string StudentCode { get; set; }

    // Audit Trail Implementations
    public long CreatorUserId { get; set; }
    public bool IsDeleted { get; set; }
    public long? DeleterUserId { get; set; }
    public DateTime? DeleteDate { get; set; }
}
Phase 2

Entity Configurations & Fluent API Rules

StudentConfig.cs

Configure entity mappings, length constraints via LengthConsts, and global soft-delete query filters using EF Core Fluent API.

public class StudentConfig : IEntityTypeConfiguration<Student>
{
    public void Configure(EntityTypeBuilder<Student> builder)
    {
        builder.Property(p => p.FirstName)
               .HasMaxLength(LengthConsts.MaxStringLen50)
               .IsRequired();

        builder.Property(p => p.LastName)
               .HasMaxLength(LengthConsts.MaxStringLen50)
               .IsRequired();

        // Global Soft Delete Query Filter
        builder.HasQueryFilter(p => !p.IsDeleted);
    }
}
Phase 3

Data Transfer Objects (DTO) & AutoMapper Integrations

StudentDto.cs

DTOs isolate database models from API outputs. Implement IHaveCustomMappings to define tailored AutoMapper projection rules.

public class StudentDto : BaseDto<Student, long>, IHaveCustomMappings
{
    public string FullName { get; set; }
    public string StudentCode { get; set; }

    public void ConfigureMapping(Profile profile)
    {
        profile.CreateMap<Student, StudentDto>()
               .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"));
    }
}
Phase 4

ViewModels (Vm) & Data Models (Dm) Pattern

ViewModels.cs & DataModels.cs

Use Vm suffix for HTTP action input parameters and Dm suffix to group multiple parameters in internal service calls.

1. Request ViewModel (Vm)
public class StudentInsertVm
{
    [Required]
    [MaxLength(50)]
    public string FirstName { get; set; }

    [Required]
    [MaxLength(50)]
    public string LastName { get; set; }
}
2. Service Data Model (Dm)
public class FilterStudentDm
{
    public string SearchTerm { get; set; }
    public int PageIndex { get; set; } = 1;
    public int PageSize { get; set; } = 10;
}
Phase 5

Service Layer & Business Operations

StudentService.cs

Encapsulate business logic inside services inheriting from GenericService to utilize built-in repository CRUD methods.

public class StudentService : GenericService<Student, long>, IStudentService
{
    public StudentService(IUnitOfWork uow) : base(uow) { }

    public async Task<long> CreateStudentAsync(StudentInsertVm vm)
    {
        var student = new Student 
        { 
            FirstName = vm.FirstName, 
            LastName = vm.LastName 
        };

        await InsertAsync(student,cancellation);

        return student.id;
    }
}
Phase 6

Presentation Layer & API Controllers

StudentController.cs

API Controllers inherit from BaseApiController and return standard unified API responses across all endpoints.

[ApiController]
[Route("api/[controller]")]
public class StudentController : BaseApiController
{
    private readonly IStudentService _studentService;

    public StudentController(IStudentService studentService)
    {
        _studentService = studentService;
    }

    [HttpPost]
    public async Task<IActionResult> Create([FromBody] StudentInsertVm vm)
    {
        var result = await _studentService.CreateStudentAsync(vm);
        return SuccessResult(result);
    }
}