Repository: abpframework/abp
Stars: 14206
.cursorrules
ABP Framework β Cursor Rules
Scope: ABP Framework repository (abpframework/abp) β for developing ABP itself, not ABP-based applications.
Goal: Enforce ABP module architecture best practices (DDD, layering, DB/ORM independence),
maintain backward compatibility, ensure extensibility, and align with ABP contribution guidelines.
Global Defaults
- Follow existing patterns in this repository first. Before generating new code, search for similar implementations and mirror their structure, naming, and conventions.
- Prefer minimal, focused diffs. Avoid drive-by refactors and formatting churn.
- Preserve public APIs. Avoid breaking changes unless explicitly requested and justified.
- Keep layers clean. Do not introduce forbidden dependencies between packages.
Module / Package Architecture (Layering)
- Use a layered module structure with explicit dependencies:
- *.Domain.Shared: constants, enums, shared types safe for all layers and 3rd-party clients. MUST NOT contain entities, repositories, domain services, or business objects.
- *.Domain: entities/aggregate roots, repository interfaces, domain services.
- *.Application.Contracts: application service interfaces and DTOs.
- *.Application: application service implementations.
- .EntityFrameworkCore / .MongoDb: ORM integration packages depend on *.Domain only. MUST NOT depend on other layers.
- .HttpApi: REST controllers. MUST depend ONLY on .Application.Contracts (NOT *.Application).
- .HttpApi.Client: remote client proxies. MUST depend ONLY on .Application.Contracts.
- .Web: UI. MUST depend ONLY on .HttpApi.
- Enforce dependency direction:
- Web -> HttpApi -> Application.Contracts
- Application -> Domain + Application.Contracts
- Domain -> Domain.Shared
- ORM integration -> Domain
- Do not leak web concerns into application/domain.
Domain Layer β Entities & Aggregate Roots
- Define entities in the domain layer.
- Entities must be valid at creation:
- Provide a primary constructor that enforces invariants.
- Always include a protected parameterless constructor for ORMs.
- Always initialize sub-collections in the primary constructor.
- Do NOT generate Guid keys inside constructors; accept
id and generate using IGuidGenerator from the calling code.- Make members
virtual where appropriate (ORM/proxy compatibility).- Protect consistency:
- Use non-public setters (private/protected/internal) when needed.
- Provide meaningful domain methods for state transitions; prefer returning
this from setters when applicable.- Aggregate roots:
- Always use a single
Id property. Do NOT use composite keys.- Prefer
Guid keys for aggregate roots.- Inherit from
AggregateRoot<TKey> or audited base classes as required.- Aggregate boundaries:
- Keep aggregates small. Avoid large sub-collections unless necessary.
- References:
- Reference other aggregate roots by Id only.
- Do NOT add navigation properties to other aggregate roots.
Repositories
- Define repository interfaces in the domain layer.
- Create one dedicated repository interface per aggregate root (e.g.,
IProductRepository).- Public repository interfaces exposed by modules:
- SHOULD inherit from
IBasicRepository<TEntity, TKey> (or IReadOnlyRepository<...> when suitable).- SHOULD NOT expose
IQueryable in the public contract.- Internal implementations MAY use
IRepository<TEntity, TKey> and IQueryable as needed.- Do NOT define repositories for non-aggregate-root entities.
- Repository method conventions:
- All methods async.
- Include optional
CancellationToken cancellationToken = default in every method.- For single-entity returning methods: include
bool includeDetails = true.- For list returning methods: include
bool includeDetails = false.- Do NOT return composite projection classes like
UserWithRoles. Use includeDetails for eager-loading.- Avoid projection-only view models from repositories by default; only allow when performance is critical.
Domain Services
- Define domain services in the domain layer.
- Default: do NOT create interfaces for domain services unless necessary (mocking/multiple implementations).
- Naming: use
*Manager suffix.- Domain service methods:
- Focus on operations that enforce domain invariants and business rules.
- Query methods are acceptable when they encapsulate domain-specific lookup logic (e.g., normalized lookups, caching, complex resolution). Simple queries belong in repositories.
- Define methods that mutate state and enforce domain rules.
- Use specific, intention-revealing names (avoid generic
UpdateXAsync).- Accept valid domain objects as parameters; do NOT accept/return DTOs.
- On rule violations, throw
BusinessException (or custom business exceptions).- Use unique, namespaced error codes suitable for localization (e.g.,
IssueTracking:ConcurrentOpenIssueLimit).- Do NOT depend on authenticated user logic; pass required values from application layer.
Application Services (Contracts + Implementation)
Contracts
- Define one interface per application service in *.Application.Contracts.
- Interfaces must inherit from
IApplicationService.- Naming:
I*AppService.- Do NOT accept/return entities. Use DTOs and primitive parameters.
Method Naming & Shapes
- All service methods async and end with
Async.- Do not repeat entity names in method names (use
GetAsync, not GetProductAsync).- Standard CRUD:
-
GetAsync(Guid id) returns a detailed DTO.-
GetListAsync(QueryDto queryDto) returns a list of detailed DTOs.-
CreateAsync(CreateDto dto) returns detailed DTO.-
UpdateAsync(Guid id, UpdateDto dto) returns detailed DTO (id MUST NOT be inside update DTO).-
DeleteAsync(Guid id) returns void/Task.-
GetListAsync query DTO:- Filtering/sorting/paging fields optional with defaults.
- Enforce a maximum page size for performance.
DTO Usage
- Inputs:
- Do not include unused properties.
- Do NOT share input DTOs between methods.
- Do NOT use inheritance between input DTOs (except rare abstract base DTO cases; be very cautious).
Implementation
- Application layer must be independent of web.
- Implement interfaces in *.Application, name
ProductAppService for IProductAppService.- Inherit from
ApplicationService.- Make all public methods
virtual.- Avoid private helper methods; prefer
protected virtual helpers for extensibility.- Data access:
- Use dedicated repositories (e.g.,
IProductRepository).- Do NOT use generic repositories.
- Do NOT put LINQ/SQL queries inside application service methods; repositories perform queries.
- Entity mutation:
- Load required entities from repositories.
- Mutate using domain methods.
- Call repository
UpdateAsync after updates (do not assume change tracking).- Extra properties:
- Use
MapExtraPropertiesTo or configure object mapper for MapExtraProperties.- Files:
- Do NOT use web types like
IFormFile or Stream in application services.- Controllers handle upload; pass
byte[] (or similar) to application services.- Cross-application-service calls:
- Do NOT call other application services within the same module.
- For reuse, push logic into domain layer or extract shared helpers carefully.
- You MAY call other modulesβ application services only via their Application.Contracts.
DTO Conventions
- Define DTOs in *.Application.Contracts.
- Prefer ABP base DTO types (
EntityDto<TKey>, audited DTOs).- For aggregate roots, prefer extensible DTO base types so extra properties can map.
- DTO properties: public getters/setters.
- Input DTO validation:
- Use data annotations.
- Reuse constants from Domain.Shared wherever possible.
- Avoid logic in DTOs; only implement
IValidatableObject when necessary.- Do NOT use
[Serializable] attribute (BinaryFormatter is obsolete); ABP uses JSON serialization.- Output DTO strategy:
- Prefer a Basic DTO and a Detailed DTO; avoid many variants.
- Detailed DTOs: include reference details as nested basic DTOs; avoid duplicating raw FK ids unnecessarily.
EF Core Integration
- Define a separate DbContext interface + class per module.
- Do NOT rely on lazy loading; do NOT enable lazy loading.
- DbContext interface:
- Inherit from
IEfCoreDbContext.- Add
[ConnectionStringName("...")].- Expose
DbSet<TEntity> ONLY for aggregate roots.- Do NOT include setters in the interface.
- DbContext class:
- Inherit
AbpDbContext<TDbContext>.- Add
[ConnectionStringName("...")] and implement the interface.- Table prefix/schema:
- Provide static
TablePrefix and Schema defaulted from constants.- Use short prefixes;
Abp prefix reserved for ABP core modules.- Default schema should be
null.- Model mapping:
- Do NOT configure entities directly inside
OnModelCreating.- Create
ModelBuilder extension method ConfigureX() and call it.- Call
b.ConfigureByConvention() for each entity.- Repository implementations:
- Inherit from
EfCoreRepository<TDbContextInterface, TEntity, TKey>.- Use DbContext interface as generic parameter.
- Pass cancellation tokens using
GetCancellationToken(cancellationToken).- Implement
IncludeDetails(include) extension per aggregate root with sub-collections.- Override
WithDetailsAsync() where needed.MongoDB Integration
- Define a separate MongoDbContext interface + class per module.
- MongoDbContext interface:
- Inherit from
IAbpMongoDbContext.- Add
[ConnectionStringName("...")].- Expose
IMongoCollection<TEntity> ONLY for aggregate roots.- MongoDbContext class:
- Inherit
AbpMongoDbContext and implement the interface.- Collection prefix:
- Provide static
CollectionPrefix defaulted from constants.- Use short prefixes;
Abp prefix reserved for ABP core modules.- Mapping:
- Do NOT configure directly inside
CreateModel.- Create
IMongoModelBuilder extension method ConfigureX() and call it.- Repository implementations:
- Inherit from
MongoDbRepository<TMongoDbContextInterface, TEntity, TKey>.- Pass cancellation tokens using
GetCancellationToken(cancellationToken).- Ignore
includeDetails for MongoDB in most cases (documents load sub-collections).- Prefer
GetQueryableAsync() to ensure ABP data filters are applied.ABP Module Classes
- Every package must have exactly one
AbpModule class.- Naming:
Abp[ModuleName][Layer]Module (e.g., AbpIdentityDomainModule, AbpIdentityApplicationModule).- Use
[DependsOn(typeof(...))] to declare module dependencies explicitly.- Override
ConfigureServices for DI registration and configuration.- Override
OnApplicationInitialization sparingly; prefer ConfigureServices when possible.- Each module must be usable standalone; avoid hidden cross-module coupling.
Framework Extensibility
- All public and protected members should be
virtual for inheritance-based extensibility.- Prefer
protected virtual over private for helper methods to allow overriding.- Use
[Dependency(ReplaceServices = true)] patterns for services intended to be replaceable.- Provide extension points via interfaces and virtual methods.
- Document extension points with XML comments explaining intended usage.
- Consider providing
*Options classes for configuration-based extensibility.Backward Compatibility
- Do NOT remove or rename public API members without a deprecation cycle.
- Use
[Obsolete("Message. Use X instead.")] with clear migration guidance before removal.- Maintain binary and source compatibility within major versions.
- Add new optional parameters with defaults; do not change existing method signatures.
- When adding new abstract members to base classes, provide default implementations if possible.
- Prefer adding new interfaces over modifying existing ones.
Localization Resources
- Define localization resources in Domain.Shared.
- Resource class naming:
[ModuleName]Resource (e.g., IdentityResource, PermissionManagementResource).- JSON files under
/Localization/[ModuleName]/ directory.- Use
LocalizableString.Create<TResource>("Key") for localizable exceptions and messages.- All user-facing strings must be localized; no hardcoded English text in code.
- Error codes should be namespaced:
ModuleName:ErrorCode (e.g., Identity:UserNameAlreadyExists).Settings & Features
- Define settings in
*SettingDefinitionProvider in Domain.Shared or Domain.- Setting names must follow
Abp.[ModuleName].[SettingName] convention.- Define features in
*FeatureDefinitionProvider in Domain.Shared.- Feature names must follow
[ModuleName].[FeatureName] convention.- Use constants for setting/feature names; never hardcode strings.
Permissions
- Define permissions in
*PermissionDefinitionProvider in Application.Contracts.- Permission names must follow
[ModuleName].[Permission] convention.- Use constants for permission names (e.g.,
IdentityPermissions.Users.Create).- Group related permissions logically.
Event Bus & Distributed Events
- Use
ILocalEventBus for intra-module communication within the same process.- Use
IDistributedEventBus for cross-module or cross-service communication.- Define Event Transfer Objects (ETOs) in Domain.Shared for distributed events.
- ETO naming:
[EntityName][Action]Eto (e.g., UserCreatedEto, OrderCompletedEto).- Event handlers belong in the Application layer.
- ETOs should be simple, serializable, and contain only primitive types or nested ETOs.
Testing
- Unit tests:
*.Tests projects for isolated logic testing with mocked dependencies.- Integration tests:
.EntityFrameworkCore.Tests / .MongoDB.Tests for repository and DB tests.- Use
AbpIntegratedTest<TModule> or AbpApplicationTestBase<TModule> base classes.- Test modules should use
[DependsOn] on the module under test.- Use
Shouldly assertions (ABP convention).- Test both EF Core and MongoDB implementations when the module supports both.
- Include tests for permission checks, validation, and edge cases.
- Name test methods:
MethodName_Scenario_ExpectedResult or Should_ExpectedBehavior_When_Condition.Contribution Discipline (PR / Issues / Tests)
- Before significant changes, align via GitHub issue/discussion.
- PRs:
- Keep changes scoped and reviewable.
- Add/update unit/integration tests relevant to the change.
- Build and run tests for the impacted area when possible.
- Localization:
- Prefer the
abp translate workflow for adding missing translations (generate abp-translation.json, fill, apply, then PR).Review Checklist
- Layer dependencies respected (no forbidden references).
- No
IQueryable or generic repository usage leaking into application/domain.- Entities maintain invariants; Guid id generation not inside constructors.
- Repositories follow async + CancellationToken + includeDetails conventions.
- No web types in application services.
- DTOs in contracts, serializable, validated, minimal, no logic.
- EF/Mongo integration follows context + mapping + repository patterns.
- Minimal diff; no unnecessary API surface expansion.
README.md
!build and test πΉ  πΉ  πΉ  πΉ  πΉ
 πΉ  πΉ  πΉ 
ABP offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET and the ASP.NET Core platforms. It provides the fundamental infrastructure, production-ready startup templates, pre-built application modules, UI themes, tooling, guides and documentation to implement that architecture properly and automate the details and repetitive works as much as possible.

Getting Started
- The Getting Started guide can be used to create and run ABP-based solutions with different options and details.
- Quick Start is a single-part, quick-start tutorial to build a simple application with the ABP Framework. Start with this tutorial if you want to understand how ABP works quickly.
- Web Application Development Tutorial is a complete tutorial on developing a full-stack web application with all aspects of a real-life solution.
- Modular Monolith Application: A multi-part tutorial that demonstrates how to create application modules, compose and communicate them to build a monolith modular web application.
- Microservice Tutorial: A multi-part guide that walks you through building a microservice solution with ABP, from creating independent services and enabling inter-service communication to exposing them through an API Gateway and generating CRUD pages with ABP Suite.
What ABP Provides?
ABP bridges the gap between ASP.NET Core and real-world business application requirements, and makes you focus on your own business code.
The following diagram contains the core components of the ABP Platform and shows how ABP sits between ASP.NET Core and Your Application:
Architecture
ABP offers a complete architectural model to build modern enterprise software solutions. Here, the fundamental architectural structures offered and first-class supported by ABP:
* Domain Driven Design (DDD)
* Microservices
* Modularity
* Multi-Tenancy
Infrastructure
There are a lot of infrastructure features provided by the ABP Framework to achieve real-world scenarios easier, like Event Bus, Background Job System, Audit Logging, BLOB Storing, Data Seeding, Data Filtering, and much more.
#### Cross-Cutting Concerns
ABP also simplifies (and even automates wherever possible) cross-cutting concerns and common non-functional requirements like Exception Handling, Validation, Authorization, Localization, Caching, Dependency Injection, Setting Management, etc.
Application Modules
ABP is a modular framework and the application modules provide pre-built application functionalities.
Some examples:
- Account: Provides UI for the account management and allows user to login/register to the application.
- CMS Kit: Brings CMS (Content Management System) capabilities to your application.
- Identity: Manages organization units, roles, users and their permissions based on the Microsoft Identity library.
- OpenIddict: Integrates to OpenIddict library and provides a management UI.
- SaaS: Manages tenants and editions for a multi-tenant (SaaS) application.
See all official modules.
Startup Templates
The Startup templates are pre-built Visual Studio solution templates. You can create your own solution based on these templates to immediately start your development.
Tooling
ABP provides CLI and UI tools to simplify your daily development work flows.
#### ABP Studio
ABP Studio is a cross-platform desktop application for ABP developers.
It is well integrated to the ABP Framework and aims to provide a comfortable development environment for you by automating things, providing insights about your solution, making develop, run and deploy your solutions much easier.
#### ABP Suite
ABP Suite allows you to automatically generate web pages in a matter of minutes.
#### ABP CLI
ABP CLI is a command line tool to perform common operations for ABP based solutions.
Mastering ABP Framework Book
This book will help you to gain a complete understanding of the ABP Framework and modern web application development techniques. It is written by the creator and team lead of the ABP Framework. You can buy from Amazon or Packt Publishing. Find further info about the book at abp.io/books/mastering-abp-framework.
The Community
ABP Community Web Site
The ABP Community is a central hub to publish articles and share knowledge about the ABP Framework.
Blog
Follow the ABP Blog to learn the latest happenings in the ABP Framework.
Samples
See the sample projects built with the ABP Framework.
Want to Contribute?
ABP is a community-driven open-source project. See the contribution guide if you want to participate in this project.
Official Links
* Home Website
* Get Started
* Features
* Documents
* Samples
* Blog
* Community
* Stackoverflow
* Twitter
Support ABP
GitHub repository stars are an important indicator of popularity and the size of the community. If you like ABP Framework, support us by clicking the star :star: on the repository.
Discord Server
We have a Discord server where you can chat with other ABP users. Share your ideas, report technical issues, showcase your creations, share the tips that worked for you and catch up with the latest news and announcements about ABP Framework. Join π https://abp.io/join-discord.