Back to Abp

ABP Dependency Rules

.agents/skills/abp-dependency-rules/SKILL.md

10.3.04.3 KB
Original Source

ABP Dependency Rules

Core Principles (All Templates)

These principles apply regardless of solution structure:

  1. Domain logic never depends on infrastructure (no DbContext in domain/application)
  2. Use abstractions (interfaces) for dependencies
  3. Higher layers depend on lower layers, never the reverse
  4. Data access through repositories, not direct DbContext

Layered Template Structure

Note: This section applies to layered templates (app, module). Single-layer and microservice templates have different structures.

Domain.Shared    → Constants, enums, localization keys
       ↑
    Domain       → Entities, repository interfaces, domain services
       ↑
Application.Contracts → App service interfaces, DTOs
       ↑
  Application    → App service implementations
       ↑
   HttpApi       → REST controllers (optional)
       ↑
     Host        → Final application with DI and middleware

Layered Dependency Direction

ProjectCan ReferenceReferenced By
Domain.SharedNothingAll
DomainDomain.SharedApplication, Data layer
Application.ContractsDomain.SharedApplication, HttpApi, Clients
ApplicationDomain, ContractsHost
EntityFrameworkCore/MongoDBDomainHost only
HttpApiContracts onlyHost

Critical Rules

❌ Never Do

csharp
// Application layer accessing DbContext directly
public class BookAppService : ApplicationService
{
    private readonly MyDbContext _dbContext; // ❌ WRONG
}

// Domain depending on application layer
public class BookManager : DomainService
{
    private readonly IBookAppService _appService; // ❌ WRONG
}

// HttpApi depending on Application implementation
public class BookController : AbpController
{
    private readonly BookAppService _bookAppService; // ❌ WRONG - Use interface
}

✅ Always Do

csharp
// Application layer using repository abstraction
public class BookAppService : ApplicationService
{
    private readonly IBookRepository _bookRepository; // ✅ CORRECT
}

// Domain service using domain abstractions
public class BookManager : DomainService
{
    private readonly IBookRepository _bookRepository; // ✅ CORRECT
}

// HttpApi depending on contracts only
public class BookController : AbpController
{
    private readonly IBookAppService _bookAppService; // ✅ CORRECT
}

Repository Pattern Enforcement

Interface Location

csharp
// In Domain project
public interface IBookRepository : IRepository<Book, Guid>
{
    Task<Book> FindByNameAsync(string name);
}

Implementation Location

csharp
// In EntityFrameworkCore project
public class BookRepository : EfCoreRepository<MyDbContext, Book, Guid>, IBookRepository
{
    // Implementation
}

// In MongoDB project
public class BookRepository : MongoDbRepository<MyDbContext, Book, Guid>, IBookRepository
{
    // Implementation
}

Multi-Application Scenarios

When you have multiple applications (e.g., Admin + Public API):

Vertical Separation

MyProject.Admin.Application      - Admin-specific services
MyProject.Public.Application     - Public-specific services
MyProject.Domain                 - Shared domain (both reference this)

Rules

  • Admin and Public application layers MUST NOT reference each other
  • Share domain logic, not application logic
  • Each vertical can have its own DTOs even if similar

Enforcement Checklist (Layered Templates)

When adding a new feature:

  1. Entity changes? → Domain project
  2. Constants/enums? → Domain.Shared project
  3. Repository interface? → Domain project (only if custom queries needed)
  4. Repository implementation? → EntityFrameworkCore/MongoDB project
  5. DTOs and service interface? → Application.Contracts project
  6. Service implementation? → Application project
  7. API endpoint? → HttpApi project (if not using auto API controllers)

Common Violations to Watch

ViolationImpactFix
DbContext in ApplicationBreaks DB independenceUse repository
Entity in DTOExposes internalsMap to DTO
IQueryable in interfaceBreaks abstractionReturn concrete types
Cross-module app service callTight couplingUse events or domain