Adding Service & New Entity (Part 3)
Mastering Built-in Repositories, Service Types, and Asynchronous Operations in AUA
Services & Built-in Repositories
All business logic in the AUA framework is implemented via services within the service layer. The service layer leverages the Service Infrastructure layer, automatically connecting each service to its respective repository. This isolates developers from manual repository-service wiring so they can focus strictly on core business rules.
For instance, implementing a service for the Student entity requires:
- Creating an interface for the Student entity inheriting from
IGenericEntityService. - Creating the concrete service class under the Services directory.
- Inheriting from
GenericEntityServiceand implementing your custom business interface. All standard repository functions are added automatically!
Service Categories in AUA Framework
The framework provides specialized service types tailored for every application layer and requirement:
Built-in repository support for entity CRUD operations and entity-specific business logic.
Dedicated for custom application business rule implementations.
Cross-cutting application services such as login handling and JWT token generation.
Optimized for fast operational reporting and data listings.
Complex enterprise reporting service configurations.
Seamless access to database SQL functions and stored procedures.
Validating incoming view models and payloads sent by clients.
Centralized logging capabilities across operations.
Handlers for in-memory data caches, SQL views, and third-party external service integration providers.
Execution Formats
All primary entity service functions are natively available in three flexible execution forms:
Entity Configurations & EF Core Fluent API Patterns
Each entity in AUA can have a dedicated configuration class implementing IEntityTypeConfiguration<T> to manage property lengths, composite keys, non-identity keys, and global query filters.
public class StudentConfig : IEntityTypeConfiguration<Student>
{
public void Configure(EntityTypeBuilder<Student> builder)
{
builder.Property(p => p.FirstName)
.HasMaxLength(LengthConsts.MaxStringLen50);
builder.Property(p => p.LastName)
.HasMaxLength(LengthConsts.MaxStringLen50);
}
}
public class UserRoleConfig : IEntityTypeConfiguration<UserRole>
{
public void Configure(EntityTypeBuilder<UserRole> builder)
{
// Ignore standard single Id property
builder.Ignore(p => p.Id);
// Configure combined composite primary key
builder.HasKey(p => new { p.AppUserId, p.RoleId });
}
}
public class UserAccessConfig : IEntityTypeConfiguration<UserAccess>
{
public void Configure(EntityTypeBuilder<UserAccess> builder)
{
// Disables identity generation to pass custom primary key values
builder.Property(p => p.Id)
.ValueGeneratedNever();
builder.Property(p => p.Title)
.HasMaxLength(LengthConsts.MaxStringLen300);
builder.Property(p => p.IsActive)
.IsRequired();
}
}
public class AppUserConfig : IEntityTypeConfiguration<AppUser>
{
public void Configure(EntityTypeBuilder<AppUser> builder)
{
// Automatically excludes soft-deleted records from EF Core queries
builder.HasQueryFilter(p => !p.IsDeleted);
}
}
"If you think good architecture is expensive, try bad architecture."AUA Framework Philosophy