mirror of https://github.com/abpframework/abp.git
csharpabpc-sharpframeworkblazoraspnet-coredotnet-coreaspnetcorearchitecturesaasdomain-driven-designangularmulti-tenancy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.3 KiB
79 lines
2.3 KiB
---
|
|
description: "ABP Single-Layer (No-Layers) application template specific patterns"
|
|
globs: "**/src/*/*Module.cs,**/src/*/Entities/**/*.cs,**/src/*/Services/**/*.cs,**/src/*/Data/**/*.cs"
|
|
alwaysApply: false
|
|
---
|
|
|
|
# ABP Single-Layer Application Template
|
|
|
|
> **Docs**: https://abp.io/docs/latest/solution-templates/single-layer-web-application
|
|
|
|
## Solution Structure
|
|
|
|
Single project containing everything:
|
|
|
|
```
|
|
MyProject/
|
|
├── src/
|
|
│ └── MyProject/
|
|
│ ├── Data/ # DbContext, migrations
|
|
│ ├── Entities/ # Domain entities
|
|
│ ├── Services/ # Application services + DTOs
|
|
│ ├── Pages/ # Razor pages / Blazor components
|
|
│ └── MyProjectModule.cs
|
|
└── test/
|
|
└── MyProject.Tests/
|
|
```
|
|
|
|
## Key Differences from Layered
|
|
|
|
| Layered Template | Single-Layer Template |
|
|
|------------------|----------------------|
|
|
| DTOs in Application.Contracts | DTOs in Services folder (same project) |
|
|
| Repository interfaces in Domain | Use generic `IRepository<T, TKey>` directly |
|
|
| Separate Domain.Shared for constants | Constants in same project |
|
|
| Multiple module classes | Single module class |
|
|
|
|
## File Organization
|
|
|
|
Group related files by feature:
|
|
|
|
```
|
|
Services/
|
|
├── Books/
|
|
│ ├── BookAppService.cs
|
|
│ ├── BookDto.cs
|
|
│ ├── CreateBookDto.cs
|
|
│ └── IBookAppService.cs
|
|
└── Authors/
|
|
├── AuthorAppService.cs
|
|
└── ...
|
|
```
|
|
|
|
## Simplified Entity (Still keep invariants)
|
|
|
|
Single-layer templates are structurally simpler, but you may still have real business invariants.
|
|
|
|
- For **trivial CRUD** entities, public setters can be acceptable.
|
|
- For **non-trivial business rules**, still prefer encapsulation (private setters + methods) to prevent invalid states.
|
|
|
|
```csharp
|
|
public class Book : AuditedAggregateRoot<Guid>
|
|
{
|
|
public string Name { get; set; } // OK for trivial CRUD only
|
|
public decimal Price { get; set; }
|
|
}
|
|
```
|
|
|
|
## No Custom Repository Needed
|
|
|
|
Use generic repository directly - no need to define custom interfaces:
|
|
|
|
```csharp
|
|
public class BookAppService : ApplicationService
|
|
{
|
|
private readonly IRepository<Book, Guid> _bookRepository;
|
|
|
|
// Generic repository is sufficient for single-layer apps
|
|
}
|
|
```
|
|
|