Uno dei punti di forza di Aspire è la sua capacità di semplificare lo sviluppo di applicazioni distribuite. Ma per sfruttarlo al meglio è importante capire come è organizzato e quali sono i concetti fondamentali che lo compongono. In questo articolo esploreremo l’architettura di Aspire: come sono strutturati i progetti, come vengono gestite le risorse e in che modo tutto si integra in un unico modello applicativo.
Una visione a più livelli
Possiamo immaginare l’architettura di Aspire su tre livelli principali:
L’AppHost si occupa di orchestrare i progetti applicativi e di collegarli alle risorse esterne. L’idea è quella di avere un grafo delle dipendenze chiaro e centralizzato, dove ogni nodo rappresenta un progetto o una risorsa, e ogni collegamento rappresenta una dipendenza.
L’AppHost
Il progetto AppHost è un’applicazione console che descrive la tua soluzione distribuita. È qui che definisci quali progetti fanno parte dell’applicazione e quali risorse servono.
Esempio:
var builder = DistributedApplication.CreateBuilder(args);
// Aggiungiamo un’API
var api = builder.AddProject<Projects.MyApi>("api");
// Aggiungiamo un frontend Blazor var frontend = builder.AddProject<Projects.MyFrontend>("frontend");
// Aggiungiamo un database Postgres var db = builder.AddPostgres("postgres") .WithDataVolume() .AddDatabase("appdb"); // Colleghiamo API e DB api.WithReference(db);
// Colleghiamo frontend e API frontend.WithReference(api);
builder.Build().Run();
In questo esempio, l’AppHost sa che:
I progetti applicativi
I progetti applicativi non sono diversi dai normali progetti .NET che già conosci: possono essere API REST, frontend Blazor, worker service o librerie di classi.
La differenza è che, quando vengono eseguiti sotto Aspire, ricevono automaticamente:
Ad esempio, un’API collegata a un database Postgres riceverà in automatico la connection string chiamata appdb, senza doverla dichiarare a mano.
Le risorse esterne
Le risorse esterne in Aspire possono essere di due tipi:
Puoi dichiararle in modo uniforme dentro l’AppHost. Ad esempio, per aggiungere RabbitMQ:
builder.AddContainer("rabbitmq", "rabbitmq:3-management")
.WithEndpoint("amqp", 5672)
.WithEndpoint("management", 15672);
A questo punto, ogni progetto che fa riferimento a rabbitmq riceverà la connection string giusta.
Un esempio di architettura completa
Immaginiamo un sistema di e-commerce molto semplice:
L’AppHost potrebbe essere:
var builder = DistributedApplication.CreateBuilder(args);
// Database SQL Server var sql = builder.AddSqlServer("sqlserver") .WithDataVolume() .AddDatabase("shopdb");
// RabbitMQ
var rabbit = builder.AddContainer("rabbitmq", "rabbitmq:3-management") .WithEndpoint("amqp", 5672) .WithEndpoint("management", 15672);
// API connessa al DB e a RabbitMQ var api = builder.AddProject<Projects.MyApi>("api") .WithReference(sql) .WithReference(rabbit);
// Frontend collegato all’API builder.AddProject<Projects.MyFrontend>("frontend") .WithReference(api);
builder.Build().Run();
Grazie a questa definizione, Aspire conosce la topologia completa della nostra applicazione e può orchestrarla in modo coerente.
Cosa fa Aspire dietro le quinte
Nell’esempio dell’e-commerce, Aspire svolge diversi compiti fondamentali che altrimenti dovresti gestire manualmente:
In questo modo, Aspire diventa un vero e proprio orchestratore di sviluppo, riducendo enormemente la complessità di setup e mantenimento.
Conclusioni
L’architettura di Aspire si basa su concetti semplici ma potenti: AppHost, progetti e risorse. Il loro legame forma un grafo di dipendenze chiaro, che Aspire è in grado di orchestrare in automatico.
Questo approccio ti permette di concentrarti solo sulla logica applicativa, sapendo che tutto il resto – dall’avvio dei container alla configurazione delle variabili d’ambiente – è gestito in modo uniforme.
Nel prossimo articolo parleremo di configurazione e gestione delle dipendenze, per capire come Aspire centralizza le impostazioni e rende più sicura la gestione dei secret.
Happy coding, Ivano.
Spoiler alert : Articolo scrito con il supporto dell'intelligenza artificiale