AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Abp Ddd

skill-burakdmir-abp-skills-abp-ddd · by burakdmir

ABP Framework v10.4 DDD quick reference: Entity, AggregateRoot, repository, domain service, application service, DTO, domain events, specification, UOW. Use when designing the domain layer, entities, aggregates, or repositories in ABP.

No reviews yet
0 installs
41 views
0.0% view→install

Install

$ agentstack add skill-burakdmir-abp-skills-abp-ddd

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-burakdmir-abp-skills-abp-ddd)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Abp Ddd? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

ABP Framework — Domain Driven Design (DDD)

ABP Framework v10.4 DDD quick reference. Entity, Aggregate Root, Repository, Domain/Application Service, DTO.

Trigger

"ABP entity/aggregate root", "ABP repository", "ABP application service", "ABP DTO", "ABP domain service", "ABP unit of work", "ABP DDD".

Layers

Presentation → Application (Services, DTO, UOW) → Domain (Entity, Aggregate, Domain Service, Repo interface) → Infrastructure (EF Core/MongoDB). DDD primarily concerns Domain + Application.

Entity & Aggregate Root

public class Order : AggregateRoot
{
    public string ReferenceNo { get; private set; }
    public ICollection Lines { get; private set; }

    protected Order() { }                                  // for ORM
    public Order(Guid id, string referenceNo) : base(id)   // id from outside (IGuidGenerator)
    {
        ReferenceNo = Check.NotNullOrWhiteSpace(referenceNo, nameof(referenceNo));
        Lines = new List();
    }

    public void AddProduct(Guid productId, int count)      // behavior in the entity, private setter
    {
        if (count ` | CreationTime, CreatorId |
| `AuditedAggregateRoot` | + LastModification* |
| `FullAuditedAggregateRoot` | + IsDeleted/Deletion* (soft-delete) |

### Value Object

```csharp
public class Money : ValueObject
{
    public decimal Amount { get; private set; }
    public string Currency { get; private set; }
    protected override IEnumerable GetAtomicValues() { yield return Amount; yield return Currency; }
}

Domain Service

public class OrderManager : DomainService   // *Manager suffix
{
    private readonly IOrderRepository _orderRepository;
    public OrderManager(IOrderRepository orderRepository) => _orderRepository = orderRepository;

    public async Task CreateAsync(string referenceNo)
    {
        if (await _orderRepository.FindByReferenceAsync(referenceNo) != null)
            throw new BusinessException("Orders:ReferenceAlreadyExists");
        return new Order(GuidGenerator.Create(), referenceNo);   // base class GuidGenerator
    }
}

Use: when a rule doesn't fit a single entity / when multiple aggregates are needed. Take/return domain objects, not DTOs; don't depend on the authenticated user.

Domain Events

public void Complete()
{
    Status = OrderStatus.Completed;
    AddLocalEvent(new OrderCompletedEvent(Id));            // same transaction, synchronous
    AddDistributedEvent(new OrderCompletedEto { OrderId = Id }); // asynchronous, ETO
}

public class OrderCompletedHandler : ILocalEventHandler, ITransientDependency
{
    public async Task HandleEventAsync(OrderCompletedEvent e) { }
}

// ETO → *.Domain.Shared
[EventName("Orders.OrderCompleted")]
public class OrderCompletedEto { public Guid OrderId { get; set; } }

Application Layer

public class BookDto : AuditedEntityDto { public string Name { get; set; } public float Price { get; set; } }

public class CreateUpdateBookDto
{
    [Required, StringLength(128)] public string Name { get; set; }
    [Required] public float Price { get; set; }
}

Rule: never expose entities, always DTOs.

Object Mapping (Mapperly — default in v10.4)

[Mapper]
public partial class BookMapper : MapperBase
{
    public override partial BookDto Map(Book source);
    public override partial void Map(Book source, BookDto destination);
}
// Module: [DependsOn(typeof(AbpMapperlyModule))] + context.Services.AddMapperlyObjectMapper();
var dto = ObjectMapper.Map(book);

> For Mapperly/AutoMapper details see the [Object Mapping skill](../abp-object-mapping/SKILL.md).

Application Service

public class BookAppService : ApplicationService, IBookAppService
{
    private readonly IRepository _repo;
    public BookAppService(IRepository repo) => _repo = repo;

    [Authorize(BookStorePermissions.Books.Create)]
    public async Task CreateAsync(CreateUpdateBookDto input)
    {
        var book = new Book(GuidGenerator.Create(), input.Name, input.Price);
        await _repo.InsertAsync(book);
        return ObjectMapper.Map(book);
    }
}

CrudAppService (reduces boilerplate)

public class BookAppService
    : CrudAppService, IBookAppService
{
    public BookAppService(IRepository repository) : base(repository)
    {
        CreatePolicyName = "BookStore.Books.Create";   // GetPolicyName/UpdatePolicyName/DeletePolicyName
    }
}

Repository

// Generic (simple CRUD): IRepository  → Get/Find/Insert/Update/Delete/GetListAsync/GetPagedListAsync...

// Custom (interface in Domain, impl in EF Core layer)
public interface IBookRepository : IRepository { Task FindByNameAsync(string name); }
public class BookRepository : EfCoreRepository, IBookRepository { /* ... */ }

// Eager loading
var q = await _orderRepository.WithDetailsAsync(x => x.Lines);
var list = await AsyncExecuter.ToListAsync(q);

> Don't expose IQueryable; don't return a projection class. Details: [EF Core](../abp-efcore/SKILL.md).

Unit of Work

UOW is automatic in app service / controller / repository methods. HTTP GET is not transactional.

await _repo.InsertAsync(entity, autoSave: true);            // preferred
[UnitOfWork(IsTransactional = false)] public virtual async Task FooAsync() { }
using (var uow = _uowManager.Begin(requiresNew: true)) { /* ... */ await uow.CompleteAsync(); }

Specification

public class ProductsByCategorySpec : Specification
{
    private readonly Guid _categoryId;
    public ProductsByCategorySpec(Guid id) => _categoryId = id;
    public override Expression> ToExpression() => p => p.CategoryId == _categoryId && !p.IsDeleted;
}
var products = await _productRepository.GetListAsync(new ProductsByCategorySpec(categoryId));

Extra Properties

user.SetProperty("Title", "Dr.");
var title = user.GetProperty("Title");

Best Practices

  1. Aggregate Root + protected setter + constructor validation
  2. Use DTOs, don't expose entities
  3. Mapperly [Mapper] partial class
  4. IGuidGenerator.Create() sequential GUID, Clock for time
  5. Soft-delete → FullAuditedAggregateRoot
  6. Reduce boilerplate with CrudAppService, rely on UOW conventions

Related

  • [EF Core](../abp-efcore/SKILL.md) · [MongoDB](../abp-mongodb/SKILL.md) · [Object Mapping](../abp-object-mapping/SKILL.md) · [Validation](../abp-validation/SKILL.md) · [Dependency Rules](../abp-dependency-rules/SKILL.md) · [Development Flow](../abp-development-flow/SKILL.md)
  • ABP Docs: https://abp.io/docs/latest/framework/architecture/domain-driven-design

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.