Arhitectură DDD în .NET Core: Cum structuri proiectele backend în mod curat și scalabil
🔰 1. Ce este Domain-Driven Design (DDD)?
- Inventat de Eric Evans, axat pe modele centrate pe domeniu.
 - Separă codul în limbajul experților (Ubiquitous Language).
 - 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
