Arhitectură DDD în .NET Core: Cum structuri proiectele backend în mod curat și scalabil

  • Doru Bulubasa
  • 28 May 2025

🔰 1. Ce este Domain-Driven Design (DDD)?

  1. Inventat de Eric Evans, axat pe modele centrate pe domeniu.
  2. Separă codul în limbajul experților (Ubiquitous Language).
  3. Avantajele majore:

  • Cod ușor de testat
  • Separare clară a responsabilităților
  • Scalabilitate logică pe termen lung

📐 2. Structurarea soluției .NET Core în layere (proiecte)

Organizarea recomandată a soluției:
/src
  ├── Blog.Domain           <- modele, entități, Value Objects
  ├── Blog.Application      <- servicii de aplicație, comenzi, DTO-uri
  ├── Blog.Infrastructure   <- EF Core, repositories, external deps
  └── Blog.API              <- Web API Controllers, DI, prezentare
Explicarea fiecărui layer:
    • Domain: logică pură, fără dependențe externe
    • Application: orchestrare între servicii, fără acces direct la DB
    • Infrastructure: detalii tehnice (SQL, Redis, Email)
    • API: controlere, autentificare, DTO-uri externe

🧱 3. Modelul de domeniu – Crearea agregatului Post

public class Post : Entity<Guid>
{
    public Title Title { get; private set; }
    public Slug Slug { get; private set; }
    public PostContent Content { get; private set; }
    public DateTime PublishedAt { get; private set; }

    public Post(Title title, Slug slug, PostContent content)
    {
        Title = title;
        Slug = slug;
        Content = content;
        PublishedAt = DateTime.UtcNow;
    }
}

Value Object: Slug

public class Slug : ValueObject
{
    public string Value { get; }

    private Slug(string value)
    {
        Value = value;
    }

    public static Slug FromTitle(string title)
    {
        var slug = Regex.Replace(title.ToLower(), @"[^a-z0-9]+", "-");
        return new Slug(slug.Trim('-'));
    }

    protected override IEnumerable<object> GetEqualityComponents()
    {
        yield return Value;
    }
}

📦 4. Repository Pattern + Unit of Work

Interfață generică:
public interface IRepository<T> where T : class
{
    Task<T?> GetByIdAsync(Guid id);
    Task AddAsync(T entity);
    void Remove(T entity);
}

Unit of Work:
public interface IUnitOfWork
{
    Task<int> SaveChangesAsync();
}

În Infrastructure, vom implementa PostRepository cu EF Core.


💡 5. Application Layer + MediatR

Comandă de creare post:

public record CreatePostCommand(string Title, string Content) : Irequest<Guid>;

Handler:

public class CreatePostHandler : IRequestHandler<CreatePostCommand, Guid>
{
    private readonly IPostRepository _postRepo;
    private readonly IUnitOfWork _uow;

    public CreatePostHandler(IPostRepository postRepo, IUnitOfWork uow)
    {
        _postRepo = postRepo;
        _uow = uow;
    }

    public async Task<Guid> Handle(CreatePostCommand request, CancellationToken ct)
    {
        var slug = Slug.FromTitle(request.Title);
        var post = new Post(new Title(request.Title), slug, new PostContent(request.Content));
        await _postRepo.AddAsync(post);
        await _uow.SaveChangesAsync();
        return post.Id;
    }
}

🔚 Concluzie

Acest articol marchează începutul implementării backend-ului nostru folosind DDD în .NET Core. Am discutat conceptele cheie, structura proiectului și am implementat un prim agregat (Post) cu pattern-uri robuste.

🧭 Ce urmează

În articolul următor, vom:
    • Adăuga un controller REST pentru POST /posts
    • Conecta frontend-ul React la acest endpoint
    • Afișa și trimite articole din UI

🤖 Întreabă AI despre acest articol

AI Răspuns generat de AI pe baza acestui articol.
AI scrie răspunsul…

Scrie un comentariu

Adresa de mail nu va fi publicata. Campurile obligatorii sunt marcate cu *