Passa al contenuto principale

Organizzazione di Core

Si organizza per dominio, non per tipo tecnico (Screaming Architecture):

NomeSoluzione.Core/
├── Ordini/
│ ├── GestoreScorte.cs # Domain service
│ ├── OrdineValidator.cs # Validator
│ └── OrdiniServiceCollectionExtensions.cs # services.AddOrdini()
├── Clienti/
│ ├── ClienteValidator.cs
│ └── ClientiServiceCollectionExtensions.cs
└── UseCases/ # comandi completi — vedi 04-usecases
├── Ordini/
│ ├── CreaOrdine.cs
│ └── ConfermaOrdine.cs
├── Clienti/
│ └── RegistraCliente.cs
└── Shared/
└── IUseCase.cs

Ogni cartella di dominio contiene comportamento: domain service, validator, e l'extension method che ne registra le dipendenze. Le entità sono in Db, i DTO ed enum sono in Models, i comandi sono in UseCases/.

❌ Da evitare:

Core/
├── Services/
├── Handlers/
└── Models/

Aprire il progetto e vedere Ordini/, Fatturazione/, Clienti/ dice immediatamente cosa fa il sistema. Vedere Services/, Handlers/, Models/ non dice nulla sul dominio — descrive solo come è costruito tecnicamente.

DI per dominio

Ogni cartella di dominio espone un extension method che registra tutte le proprie dipendenze:

// Core/Ordini/OrdiniServiceCollectionExtensions.cs
public static class OrdiniServiceCollectionExtensions
{
public static IServiceCollection AddOrdini(this IServiceCollection services)
{
services.AddScoped<GestoreScorte>();
services.AddScoped<CreaOrdine>();
services.AddScoped<ConfermaOrdine>();
services.AddScoped<IValidator<CreaOrdineDto>, OrdineValidator>();
return services;
}
}

Il composition root in Api compone i domini senza conoscerne i dettagli interni:

// Api/Program.cs
builder.Services.AddOrdini();
builder.Services.AddClienti();

Quando un dominio si sposta o si rimuove, si porta dietro le proprie registrazioni. Program.cs resta una sequenza di chiamate ad alto livello.