Installazione e configurazione di Lino CLI
Il primo passo per iniziare a lavorare con il Lino CLI Γ¨ installare lo strumento nel tuo ambiente di sviluppo.
Γ distribuito come a strumento globale dotnet, il che significa che sarΓ disponibile per qualsiasi progetto.NET sul tuo computer.
Prima dell'installazione, verificare che l'SDK.NET richiesto dai modelli attuali sia disponibile e che il terminale possa essere eseguito dotnet e che la directory degli strumenti globali.NET si trova nel file PATH.
Passaggio 1: installazione
Per installare (o aggiornare) Lino CLI, eseguire il seguente comando nel terminale:
dotnet tool install --global Tolitech.Lino
Note importanti:
- Se Γ¨ giΓ installata una versione, Γ¨ possibile utilizzare
dotnet tool update --global Tolitech.Lino aggiornare.
- Verificare che la directory degli strumenti globali.NET sia nel file
PATH del sistema in modo che il comando lino funzionare correttamente.
Passaggio 2: configura la lingua
Dopo l'installazione, si consiglia di configurare la lingua (o la cultura) che CLI utilizzerΓ nei messaggi, nelle richieste e nei registri:
lino preferences culture set
Ti verrΓ chiesto di scegliere tra le lingue disponibili. Questa impostazione garantisce che tutte le istruzioni e i messaggi vengano visualizzati in modo coerente nella lingua desiderata.
Questa preferenza modifica i messaggi, le richieste e le indicazioni localizzate CLI; non rinomina entitΓ , servizi, moduli o termini commerciali generati nel progetto.
Passaggio 3: autenticazione e registrazione
Per accedere a tutte le funzionalitΓ di Lino, inclusi modelli avanzati, pubblicazione di immagini Docker e integrazioni con servizi esterni, devi essere autenticato.
- Se non sei ancora registrato, registrati con il comando:
- Se sei giΓ registrato accedi con:
Che succede: CLI memorizza un token di autenticazione localmente, consentendoti di eseguire comandi che richiedono l'accesso a risorse protette senza dover accedere ogni volta che lo utilizzi.
Mantieni questo token privato ed evita di condividere lo stesso profilo utente tra diversi sviluppatori, agenti CI o macchine.
Passaggio 4: verifica
Per confermare che l'installazione e l'autenticazione sono andate a buon fine, eseguire:
Se il comando restituisce la versione installata, sei pronto per iniziare a utilizzare il file Lino CLI nei tuoi progetti
Creazione del progetto MyApp
In questo passaggio creeremo la struttura iniziale del progetto utilizzando il file Lino CLI.
Questo progetto servirΓ come base per dimostrare la creazione di servizi, moduli, front-end e tutta l'integrazione degli eventi.
Un progetto Lino non Γ¨ solo una cartella con una soluzione: definisce convenzioni per i limiti del servizio, le librerie condivise, l'host Aspire, il framework frontend, i test, la gestione dei pacchetti, gli analizzatori e le configurazioni che i comandi successivi riutilizzano.
Passaggio 1: esecuzione del comando di creazione
Per creare un nuovo progetto, esegui il comando seguente nel terminale:
CLI ti guiderΓ passo dopo passo, chiedendoti informazioni come:
- Nome del progetto: useremo
MyApp, ma puoi scegliere il nome che preferisci;
- FunzionalitΓ aggiuntive: analizzatori di codice, memorizzazione nella cache distribuita, supporto eventi asincroni, ecc.
Passaggio 2: configurazione delle funzionalitΓ essenziali
Per questo progetto, ti consigliamo di abilitare le seguenti funzionalitΓ fin dall'inizio:
- Analizzatori di codice: garantire che il codice segua buone pratiche e standard coerenti, prevenendo errori comuni di implementazione;
- Cache distribuita: migliora le prestazioni delle applicazioni in scenari con piΓΉ servizi, evitando query inutili al database;
- Comunicazione asincrona: consente l'utilizzo di eventi e code per l'integrazione tra servizi, garantendo scalabilitΓ e disaccoppiamento.
Γ importante abilitare tutte queste opzioni in questo progetto, poichΓ© creeremo piΓΉ servizi che comunicheranno attraverso eventi di integrazione.
Questo ti permetterΓ di capire come strutturare sistemi modulari e distribuiti utilizzando Lino.
Passaggio 3: struttura generata
Dopo aver eseguito il comando e configurato le risorse, CLI genererΓ la struttura iniziale del progetto. ComprenderΓ :
- Cartelle servizi e moduli;
- Modelli front-end (se applicabile);
- Impostazioni iniziali della cache, eventi e integrazioni;
- File di soluzione (.slnx) e di progetto (.csproj) pronti per la compilazione.
Ora il tuo progetto La miaApp Γ¨ pronto per ricevere i servizi, moduli, entitΓ e front-end che configureremo nei prossimi passi.
Prima di continuare, apri la soluzione generata ed esegui dotnet build per confermare che i riferimenti, i generatori di sorgenti, i modelli, i file di progetto e la configurazione iniziale siano coerenti.
Aggiunta dell'applicazione web Backoffice
Un sistema completo in genere necessita di almeno un'applicazione web per gestire il dominio. In questa guida l'applicazione viene chiamata Backoffice e rappresenta un'interfaccia interna per amministratori, manager o utenti operativi per monitorare prodotti, categorie, scorte, vendite e altre informazioni di sistema.
L'applicazione web non sostituisce i servizi di dominio. Agisce come punto di ingresso visivo per consumare API, attivare Commands, consultare Queries e visualizzare schermate coerenti con le regole giΓ modellate nei servizi.
Passaggio 1: esecuzione del comando di creazione
Per aggiungere una nuova applicazione web al progetto, usare:
L'alias lino webapp new Γ¨ disponibile anche per rendere piΓΉ rapida la digitazione. Durante l'esecuzione, indicare un nome chiaro per l'applicazione web; in questo esempio useremo Backoffice.
lino web-app new --name Backoffice
Passaggio 2: comprendere la struttura generata
Al termine del processo, Lino crea la struttura iniziale della Web App in src/WebApps/<WebAppName>. Per un'applicazione Blazor, la struttura puΓ² includere progetti server/client, risorse condivise, file di localizzazione, client per consumare le APIs e convenzioni che saranno usate in seguito da lino page new.
- Cartelle per pagine, componenti, layout, servizi e risorse applicative;
- Clienti HTTP e contratti richiesti per consumare API esposti dai servizi di progetto;
- Risorse di localizzazione e modelli iniziali utilizzati dall'esperienza web;
- Progetti client/server quando la tipologia di applicazione richiede questa separazione;
- Convenzioni di percorso, navigazione e integrazione che verranno riutilizzate nella generazione della pagina;
- Punti di integrazione con autenticazione e autorizzazione quando la funzionalitΓ di autenticazione viene aggiunta al progetto.
Passaggio 3: quando creare l'app Web nel flusso
Se sai giΓ che il sistema avrΓ un'interfaccia Blazor, crea la Web App subito all'inizio, dopo la creazione del progetto. In questo modo servizi, moduli, entitΓ , APIs e pagine generati successivamente saranno giΓ allineati con l'applicazione web che li consumerΓ .
Questo flusso Γ¨ particolarmente utile perchΓ© i servizi creati in seguito generano anche progetti tipizzati Api.Contracts e Api.Client, consumati dal progetto Blazor. Con la Web App presente fin dall'inizio, diventa piΓΉ semplice validare il percorso completo: dominio, API, contratti, HttpClient e schermata.
Note importanti
- Il Backoffice deve consumare i dati attraverso gli API generati, mantenendo la logica aziendale nei servizi e nei moduli corretti.
- Prima di esporre le pagine amministrative, rivedere l'autenticazione, l'autorizzazione, i ruoli, le autorizzazioni e le policy di accesso.
- Γ possibile creare piΓΉ applicazioni Web, ad esempio a
Backoffice interno e a Site pubblico, quando il pubblico, le autorizzazioni, le distribuzioni o le responsabilitΓ sono diversi.
- Evita di mescolare flussi pubblici e amministrativi nella stessa app Web quando ciΓ² rende difficili la sicurezza, la navigazione, la distribuzione o la proprietΓ del team.
Una volta creata l'applicazione web, la guida puΓ² passare ai servizi e ai moduli che forniranno i dati e le regole aziendali utilizzati da questa interfaccia.
Creazione di servizi e moduli
In questo passaggio costruiremo i servizi e i moduli che comporranno l'applicazione.
L'obiettivo Γ¨ creare un'architettura modulare e scalabile, consentendo a diverse aree del sistema, come prodotti, categorie, inventario, vendite e media, di evolversi in modo indipendente, mantenendo la coesione e facilitando la manutenzione.
I servizi definiscono i limiti di distribuzione e persistenza; I moduli organizzano le aree aziendali all'interno di un servizio modulare. Prima di creare file, valuta quali parti del dominio necessitano di un proprio database, rilascio indipendente, accordo di integrazione o proprietΓ separata.
Passaggio 1: definizione dei servizi
Inizialmente creeremo i seguenti servizi, ciascuno con responsabilitΓ ben definite:
- Catalog (modulare) β responsabile della gestione di prodotti, categorie e prezzi;
- Sales β responsabile del trattamento delle vendite e degli ordini;
- Stock β responsabile della gestione delle scorte e dei movimenti;
- Security β responsabile dellβautenticazione, autorizzazione e gestione degli utenti.
Per creare i servizi dell'esempio, eseguire un comando per ogni servizio. Nel wizard di Catalog, scegliere l'architettura modulare; per gli altri, scegliere l'architettura adatta a una frontiera semplice.
lino service new --name Catalog
lino service new --name Sales
lino service new --name Stock
lino service new --name Security
Durante l'esecuzione del comando, il CLI richiederΓ :
- Nome del servizio: per esempio,
Catalog;
- Nome visualizzato e stile architetturale: scegliere un'architettura semplice per frontiere compatte oppure modulare quando il servizio ha aree coese indipendenti;
- Database: scegliere la tecnologia piΓΉ adatta al progetto (SQL Server, PostgreSQL, ecc.);
Passaggio 2: Creazione di moduli dentro i servizi
Non tutti i servizi devono essere modulari. Nel nostro progetto, solo il servizio Catalog avrΓ moduli, per separare responsabilitΓ come merchandising e pricing.
Definiamo i seguenti moduli per il servizio Catalog:
- Merchandising β gestione di prodotti e categorie;
- Pricing β gestione di prezzi, promozioni e storico delle modifiche.
Per creare i moduli di Catalog, eseguire:
lino module new --service Catalog --name Merchandising
lino module new --service Catalog --name Pricing
Puoi creare tutti i moduli che desideri all'interno del servizio modulare Catalog.
Inoltre, a seconda della complessitΓ , alcuni moduli potrebbero in futuro diventare servizi indipendenti.
La separazione qui presentata Γ¨ solo a scopo didattico e serve come esempio di organizzazione modulare.
Non utilizzare solo i moduli per creare cartelle; usali quando proteggono un'area aziendale con le proprie entitΓ , casi d'uso, API, migrazioni ed eventi.
Struttura del progetto finale
Dopo aver creato i servizi e i moduli, la soluzione dovrebbe avere una struttura simile alla seguente:
MyApp/
βββ src/
βββ Aspire/
βββ Integrations/
βββ Services/
β βββ Catalog/
β β βββ Modules/
β β β βββ Merchandising/
β β β βββ Pricing/
β β βββ MyApp.Catalog.Host
β β βββ MyApp.Catalog.Infrastructure
β βββ Sales/
β βββ Security/
β βββ Shared/
β βββ Stock/
βββ WebApps/
βββ Backoffice/
β βββ Services/
β β βββ Catalog/
β β βββ Sales/
β β βββ Security/
β β βββ Stock/
β βββ MyApp.WebApp.Backoffice
β βββ MyApp.WebApp.Backoffice.Client
βββ Shared/
βββ MyApp.WebApp.Shared
βββ tests/
βββ Services/
βββ Catalog/
β βββ Merchandising/
β βββ Pricing/
βββ Sales/
βββ Security/
βββ Shared/
βββ Stock/
Spiegazione della struttura:
Services/: contiene tutti i servizi di sistema, ciascuno isolato con una propria logica di business, infrastruttura e hosting;
Modules/: cartelle all'interno di servizi modulari, che consentono di organizzare funzionalitΓ specifiche e mantenere il codice coeso;
WebApps/: frontend associati al sistema, giΓ integrati con i servizi;
Shared/: librerie e risorse condivise tra servizi e frontend;
tests/: test unitari e di integrazione organizzati per servizio e modulo.
Con questa struttura modulare, ogni team o sviluppatore puΓ² lavorare in modo indipendente su diverse parti del sistema, facilitando scalabilitΓ , manutenzione e test.
Dopo aver creato servizi e moduli, esegui dotnet build per confermare che i progetti siano collegati correttamente alla soluzione, host Aspire, progetti condivisi e framework di test.
Aggiunta di autenticazione e autorizzazione
L'autenticazione e l'autorizzazione sono elementi essenziali di qualsiasi sistema moderno.
L'autenticazione dimostra chi Γ¨ l'utente; l'autorizzazione definisce ciΓ² che questo utente puΓ² eseguire. En Lino CLI, la funzione di autenticazione genera la base necessaria per utenti, ruoli, autorizzazioni, token, policy di accesso e integrazione con API.
Passaggio 1: esecuzione del comando di autenticazione
Per aggiungere funzionalitΓ di autenticazione e autorizzazione, utilizzare il comando:
CLI ti guiderΓ attraverso i seguenti passaggi:
-
Scelta del servizio o del modulo: Γ¨ necessario indicare dove verranno installati gli artefatti di autenticazione.
Nel nostro progetto di esempio utilizziamo il servizio Security, che centralizza tutta la logica di sicurezza del sistema;
- Impostazioni aggiuntive: creazione di tabelle di utenti, ruoli, permessi, token e configurazione di policy di accesso;
- Durata dei token: definizione della scadenza per access token e refresh token in accordo con la policy di sicurezza del prodotto;
- Tipo di identificatore utente: scegliendo la tipologia utilizzata dal modello utente e dai contratti generati.
Passaggio 2: struttura generata
Dopo aver eseguito il comando, il servizio Security conterrΓ file e cartelle come:
- Dominio/entitΓ : aggregati, entitΓ e regole per utenti, ruoli, permessi e token;
- Infrastructure/Persistence: configurazioni del database, mapping di Entity Framework e migrations per le tabelle di sicurezza;
- Application: Commands, Queries, Handlers, servizi di autenticazione, generazione di token, convalida delle credenziali e controlli dei permessi;
- API/Host: endpoint per login, logout, registrazione, refresh token e operazioni protette;
- Integrazione con l'applicazione Web: supporto per flussi autenticati quando Γ¨ presente un'applicazione web.
In questo modo, la tua applicazione disporrΓ di un'autenticazione solida e di un controllo granulare degli accessi, pronta a supportare piΓΉ utenti e diversi livelli di autorizzazioni.
Tuttavia, il codice generato dovrebbe essere trattato come una solida base, non come la revisione finale della sicurezza. Prima della produzione, esaminare la durata del token, la progettazione delle autorizzazioni, la politica delle password, HTTPS, i segreti, la limitazione della velocitΓ , i log e le configurazioni di distribuzione.
Aggiunta di Background Jobs
In sistemi distribuiti e modulari, come quello con cui stiamo costruendo Lino CLI, non tutti i servizi comunicano direttamente tra loro.
Per garantire coerenza e affidabilitΓ nello scambio di informazioni, utilizziamo eventi di integrazione.
Tuttavia, per elaborare questi eventi in modo efficiente e asincrono, abbiamo bisogno dei Background Jobs.
Lino utilizza lo standard Modello Outbox per garantire che tutti i messaggi generati dai servizi siano registrati in modo affidabile prima di essere inviati.
Con questo abbiamo ottenuto:
- Evitare la perdita di eventi in caso di interruzioni o riavvii del servizio;
- Assicurarsi che lo stesso messaggio venga inviato una sola volta;
- Consentire la rielaborazione dei messaggi in caso di mancata consegna;
- Separare l'elaborazione degli eventi dalla logica dell'applicazione principale, migliorando le prestazioni e la scalabilitΓ .
Passaggio 1: esecuzione del comando
Per aggiungere il supporto ai Background Jobs nel tuo progetto, esegui il comando:
lino feature background-job add
Il CLI ti chiederΓ di selezionare il servizio in cui verrΓ installato il Background Job. Generalmente sceglierai il servizio che centralizza la produzione di eventi, come Catalog o Sales.
Nelle opzioni correnti, la procedura guidata puΓ² anche richiedere il modulo, la libreria di job, se gli eventi Outbox devono essere elaborati, la pianificazione e la dimensione del batch. Il flusso dei template correnti usa Hangfire per l'esecuzione ricorrente dei job.
Passaggio 2: configurazione dell'esecuzione
Durante la configurazione sarΓ possibile definire:
- Intervallo di controllo: determina la frequenza con cui il processo in background controllerΓ la tabella Outbox per i nuovi messaggi. Un intervallo troppo breve puΓ² aumentare l'utilizzo delle risorse, mentre un intervallo troppo lungo puΓ² ritardare la consegna degli eventi;
- Lotto di record elaborati alla volta: controlla il numero di eventi che verranno letti e inviati per esecuzione. Batch piΓΉ grandi possono aumentare le prestazioni, ma richiedono piΓΉ memoria ed elaborazione;
- Politica di recupero: In caso di mancato invio dei messaggi, Γ¨ possibile configurare quante volte il lavoro tenterΓ di inviarli nuovamente.
Questi parametri dipendono dalle dimensioni del sistema, dalla capacitΓ della macchina e dal volume previsto di eventi.
Passaggio 3: struttura generata
Dopo la configurazione, il progetto avrΓ un lavoro in background pronto per elaborare i messaggi dalle tabelle Outbox in ogni servizio.
- Il caso d'uso cambia il dominio e registra un dominio o un evento di integrazione.
- L'unitΓ di lavoro salva i dati aziendali e i messaggi da Outbox nella stessa transazione.
- Hangfire esegue job ricorrenti che leggono i messaggi in sospeso in batch.
- I messaggi vengono pubblicati nel motore di integrazione configurato come RabbitMQ quando la comunicazione asincrona Γ¨ abilitata.
- I messaggi completati, non riusciti, vecchi o bloccati possono essere gestiti dalla logica e dalla configurazione generata per il lavoro.
CiΓ² garantisce che tutti gli eventi di integrazione vengano elaborati in modo affidabile ed efficiente, consentendo a piΓΉ servizi e moduli di comunicare in modo asincrono, senza influire sulle prestazioni del sistema principale.
La regola operativa piΓΉ importante Γ¨ mantenere chiaro il confine transazionale: gli eventi che devono essere inviati tramite Outbox devono essere creati nello stesso flusso transazionale del cambiamento aziendale che rappresentano.
Creazione di entitΓ ed enumerazioni
In questa sezione descriveremo in dettaglio la progettazione delle entitΓ , delle enumerazioni e dei Value Objects dell'applicazione, mostrando in quali servizi e moduli verrΓ creato ciascun elemento.
1. Creazione dell'entitΓ Category
Per creare l'entitΓ Category nel servizio Catalog e nel modulo Merchandising, eseguire:
lino entity new --service Catalog --module Merchandising --name Category
L'entitΓ verrΓ creata nel servizio Catalog e nel modulo Merchandising con la seguente struttura:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β PK β FK β Property name β Type β Length β Required β Auto-increment β
ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β x β β Id β Guid β β x β x β
ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Name β string β 50 β x β β
ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
2. Creazione dell'entitΓ Product
Successivamente creiamo l'entitΓ Product nello stesso servizio e modulo. In questo flusso, il Value Object ProductDimension e l'enum ProductStatus vengono configurati all'interno del wizard di creazione dell'entitΓ , come parte dell'aggregato Product:
lino entity new --service Catalog --module Merchandising --name Product
Durante l'esecuzione, aggiungere le proprietΓ semplici, la relazione con Category, la proprietΓ Dimensions di tipo Value Object e la proprietΓ Status di tipo Enum.
ββββββ¬βββββ¬ββββββββββββββββ¬ββββββββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β PK β FK β Property name β Type β Length β Required β Auto-increment β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β x β β Id β Guid β β x β x β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Name β string β 100 β x β β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Description β string β 500 β x β β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Price β decimal β β x β β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β x β CategoryId β Category β β x β β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Dimensions β ValueObject β β β β
ββββββΌβββββΌββββββββββββββββΌββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Status β Enum β β x β β
ββββββ΄βββββ΄ββββββββββββββββ΄ββββββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
2.1 Configurazione del Value Object ProductDimension dentro Product
Nello scenario di questa guida, ProductDimension non viene creato con un comando separato. Viene aggiunto durante il lino entity new di Product, come proprietΓ Dimensions, e rappresenta le dimensioni del prodotto:
βββββββββββββββββ¬ββββββββββ¬βββββββββ¬βββββββββββ
β Property name β Type β Length β Required β
βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€
β Width β decimal β β x β
βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€
β Height β decimal β β x β
βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€
β Depth β decimal β β x β
βββββββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββ
Nota: il comando lino value-object new esiste per scenari in cui il Value Object deve essere creato separatamente. In questi casi, usare gli argomenti del servizio e del modulo di destinazione:
lino value-object new --service <ServiceName> --module <ModuleName> --name <ValueObjectName>
2.2 Configurazione della Enum ProductStatus dentro Product
Allo stesso modo, ProductStatus viene configurata dentro il lino entity new di Product, come proprietΓ Status. Definisce lo stato del prodotto:
βββββββββ¬βββββββββββββββ¬βββββββββββββββ
β Value β Name β Display Name β
βββββββββΌβββββββββββββββΌβββββββββββββββ€
β 1 β Active β Active β
βββββββββΌβββββββββββββββΌβββββββββββββββ€
β 2 β Inactive β Inactive β
βββββββββΌβββββββββββββββΌβββββββββββββββ€
β 3 β Discontinued β Discontinued β
βββββββββ΄βββββββββββββββ΄βββββββββββββββ
Nota: il comando lino enumeration new puΓ² essere usato anche quando una enum deve essere creata separatamente in un altro scenario:
lino enumeration new --service <ServiceName> --module <ModuleName> --name <EnumerationName>
3. Aggiunta di nuove proprietΓ
Man mano che il progetto evolve, possiamo modificare le entitΓ esistenti per aggiungere nuove proprietΓ .
Ad esempio, aggiungeremo un elenco di immagini all'entitΓ Product:
lino entity edit --service Catalog --module Merchandising --entity Product
Dentro questo stesso flusso, creiamo la proprietΓ Images di tipo List<ProductImage>. PoichΓ© ProductImage appartiene all'aggregato Product, anche la sua struttura viene configurata durante il lino entity edit di Product:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββββββββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β PK β FK β Property name β Type β Length β Required β Auto-increment β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β x β β Id β Guid β β x β x β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Name β string β 100 β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Description β string β 500 β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Price β decimal β β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β x β CategoryId β EntityId β β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Dimensions β ValueObject β β β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Status β Enum β β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β x β Images β List β β β β
ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββββββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
3.1 Configurazione di ProductImage dentro Product
ProductImage non viene creato con un comando separato in questo scenario. Viene configurato come elemento della collezione Images durante la modifica di Product e ha la seguente struttura:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β PK β FK β Property name β Type β Length β Required β Auto-increment β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β x β β Id β Guid β β x β x β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β x β ProductId β EntityId β β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β UploadDate β DateTimeOffset β β x β β
ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Image β File β β x β β
ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
Nota: il comando lino entity new esiste per creare entitΓ indipendenti in altri scenari. Quando l'entitΓ non fa parte della modifica di un aggregato esistente, usare:
lino entity new --service <ServiceName> --module <ModuleName> --name <EntityName>
4. Creazione di entitΓ per altri servizi
In servizio Sales, creiamo l'entitΓ ProductSnapshot, che sarΓ alimentato da eventi di integrazione.
PoichΓ© l'Id originale dell'entitΓ Product proviene dal servizio Catalog, qui non puΓ² essere autoincrementale.
lino entity new --service Sales --name ProductSnapshot
ββββββ¬βββββ¬ββββββββββββββββ¬ββββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β PK β FK β Property name β Type β Length β Required β Auto-increment β
ββββββΌβββββΌββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β x β β Id β Guid β β x β β
ββββββΌβββββΌββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Name β string β 100 β x β β
ββββββΌβββββΌββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Price β decimal β β x β β
ββββββ΄βββββ΄ββββββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
Nota: solo i campi essenziali sono stati replicati in ProductSnapshot per il servizio Sales. Le entitΓ complementari, come Customer, Order e StockItem, non saranno dettagliate qui per semplificare la documentazione. ProductSnapshot funziona come una shadow entity: una copia locale, minima e controllata di dati il cui proprietario si trova in un altro servizio. Questo consente a Sales di consultare i dati di prodotto necessari senza dipendere direttamente dall'entitΓ o dal database di Catalog.
Questo tipo di struttura potrebbe essere creato anche con il comando lino shadow new, alias di lino shadow-entity new. In questo flusso, Lino copia la struttura di un'entitΓ da un altro servizio o modulo e permette di selezionare solo le proprietΓ che hanno senso per il contesto consumatore.
lino shadow new --service <ServiceName> --module <ModuleName> --name <ShadowEntityName>
Nell'esempio, l'entitΓ di origine Γ¨ Catalog.Merchandising.Product e la destinazione Γ¨ il servizio Sales, mantenendo solo i campi necessari per le vendite.
Creazione di eventi e relativi Handlers
Ricapitolando, nell'argomento precedente abbiamo creato nel servizio modulare Catalog.Merchandising le entitΓ Product, Category e ProductImage, mentre nel servizio Sales abbiamo creato l'entitΓ ProductSnapshot.
Ora creiamo eventi di dominio ed eventi di integrazione. L'obiettivo Γ¨ che, quando si creano o si aggiornano prodotti nel servizio Catalog, queste modifiche vengano replicate nei servizi consumer, come Sales e Stock.
1. Creazione di eventi di dominio
Il primo passaggio consiste nel creare gli eventi di dominio ProductCreated e ProductUpdated con il comando:
Durante la creazione possiamo associare l'evento ad un gestore e, contemporaneamente, configurare l'attivazione di un evento di integrazione. CiΓ² centralizza la creazione di tutto il flusso necessario.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β Question β Answer β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select a service: β Catalog β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select a module: β Merchandising β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select a entity: β Product β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select the event type: β Domain Event β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Enter the name of the event: β ProductCreated β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Do you want to create an associated event handler? β Yes β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Trigger a integration event? β Yes β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Choose the integration event to be triggered: β (Create new integration event) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Enter the name of the event: β ProductCreated β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Which model will be used for this integration event? β Creation model β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
Allo stesso modo creiamo l'evento ProductUpdated:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β Question β Answer β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select a service: β Catalog β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select a module: β Merchandising β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select a entity: β Product β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Select the event type: β Domain Event β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Enter the name of the event: β ProductUpdated β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Do you want to create an associated event handler? β Yes β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Trigger a integration event? β Yes β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Choose the integration event to be triggered: β (Create new integration event) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Enter the name of the event: β ProductUpdated β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ€
β Which model will be used for this integration event? β Update model β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
Con questo, abbiamo:
- Eventi di dominio creati (
ProductCreated e ProductUpdated);
- Gestori di eventi di dominio corrispondenti;
- Eventi di integrazione registrati automaticamente su Outbox dal gestore eventi del dominio.
2. Creazione degli Handlers degli eventi di integrazione
Il passaggio successivo consiste nel definire quali servizi utilizzeranno gli eventi di integrazione. Per fare questo, utilizziamo:
Il flusso di creazione prevede:
- Seleziona il servizio, il modulo e l'entitΓ che conterrΓ il gestore;
- Seleziona l'evento di integrazione che verrΓ utilizzato e da quale servizio/modulo/entitΓ proverrΓ .
Ad esempio, nel servizio Sales creiamo gli Handlers per ProductCreated e ProductUpdated, che consumeranno gli eventi emessi da Catalog.Merchandising.Product:
ββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ
β Question β Answer β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select a service: β Sales β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select a entity: β ProductSnapshot β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event type: β Integration Event β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event's service to be consumed: β Catalog β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event's module to be consumed: β Merchandising β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event's entity to be consumed: β Product β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Choose the event to be consumed: β ProductCreated β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Enter the name of the event handler: β ProductCreated β
ββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ
β Question β Answer β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select a service: β Sales β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select a entity: β ProductSnapshot β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event type: β Integration Event β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event's service to be consumed: β Catalog β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event's module to be consumed: β Merchandising β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select the event's entity to be consumed: β Product β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Choose the event to be consumed: β ProductUpdated β
ββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Enter the name of the event handler: β ProductUpdated β
ββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
Con questo, abbiamo due Handlers di eventi di integrazione nel servizio Sales, che consumano solo i campi necessari dagli eventi di integrazione di Catalog.Merchandising.
CiΓ² garantisce che le tabelle replicate conservino solo i dati essenziali, ottimizzando archiviazione e prestazioni.
In termini di architettura, il flusso previsto Γ¨: l'Handler del Command modifica l'aggregato, viene generato l'evento di dominio, l'Handler prepara l'evento di integrazione, l'Outbox archivia il messaggio, il Background Job elabora la coda e il motore di messaggistica recapita il messaggio ai consumer.
CiΓ² evita l'accoppiamento sincrono tra i servizi e riduce il rischio che il database venga modificato senza che l'evento corrispondente venga pubblicato.
Generazione di pagine web, API, Commands e Queries
Uno dei grandi vantaggi di Lino CLI Γ¨ consentire la creazione integrata di pagine web, API, Commands e Queries in modo automatizzato, semplificando l'intero flusso di sviluppo.
Quando il modello di dominio Γ¨ sufficientemente stabile, questo comando crea un percorso completo dallo schermo alla persistenza, rendendo visibile all'utente finale il lavoro di modellazione svolto nei passaggi precedenti.
Per iniziare Γ¨ sufficiente eseguire il comando:
Durante il processo, dovrai:
- Seleziona il servizio, il modulo e l'entitΓ che desideri esporre;
- Scegli il tipo e il nome della pagina che verrΓ generata;
- Scegli i campi che faranno parte della lista;
- Genera automaticamente pagine di elenco (griglia impaginata) e modulo di creazione/modifica;
- Genera classi HttpClient per il consumo da parte del frontend;
- Creare contratti di richiesta/risposta e tutti i REST API necessari (POST, PUT, PATCH, DELETE e GET);
- Creare Commands, Queries, Handlers e validator, che arrivano al database garantendo il flusso CRUD completo.
Con questo comando, ottieni un'applicazione funzionale senza dover scrivere manualmente il livello di interfaccia, API e la logica aziendale, mantenendo lo standard e la coerenza tra i servizi.
Anche così, rivedi le regole aziendali e le convalide dopo la generazione, perché non tutte le regole possono essere dedotte solo dai metadati della proprietà .
Per questo progetto, possiamo generare pagine integrate per le seguenti entitΓ :
- Catalog.Merchandising.
Category
- Catalog.Merchandising.
Product
- Sales.
ProductSnapshot
Dopo aver generato le pagine, le API e Commands/Queries, l'applicazione sarΓ pronta per interagire in modo completo tra frontend e backend, con validazioni, route e persistenza giΓ configurate automaticamente dal Lino CLI.
Correre dotnet build dopo la generazione per identificare tempestivamente riferimenti interrotti, contratti incoerenti o impatti di recenti modifiche del modello.
Creazione e applicazione delle migrazioni
Dopo aver creato o modificato entitΓ , Value Objects, enumerazioni, relazioni, autenticazione, supporto Tenant o persistenza dei Background Jobs, genera migrations per mantenere database e codice allineati. La migration trasforma la modifica del modello in un artefatto esplicito, versionabile e revisionabile.
Il Lino CLI coordina questo processo con Entity Framework, selezionando il servizio/modulo corretto, usando la versione corrente del servizio e organizzando gli script generati per facilitare la tracciabilitΓ .
Passaggio 1: creazione di una migrazione
Per creare una nuova migrazione, esegui:
lino database migrations add
Il comando puΓ² anche accettare alias come lino database migrations new E lino database migrations create, ma il modo preferito nella documentazione Γ¨ add.
Durante l'esecuzione Γ¨ necessario informare:
- Il servizio che riceverΓ la migrazione, ad esempio
Catalog;
- Il modulo interessato, quando il servizio Γ¨ modulare, ad es.
Merchandising;
- La versione attuale del servizio, leggi da
src/Services/<ServiceName>/version.txt;
- Una descrizione obiettiva per la migrazione, ad esempio
Initial migration O Add product images.
βββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ
β Question β Answer β
βββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select a service: β Catalog β
βββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Select a module: β Merchandising β
βββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Current version of the service: β 0.1.0 β
βββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββ€
β Provide a description for this migration: β Initial migration β
βββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
Quando conosci giΓ il servizio e il modulo, puoi inserire direttamente questi dati:
lino database migrations add --service <ServiceName> --module <ModuleName>
Passaggio 2: cosa viene generato
Quando confermi la creazione, Lino prepara i comandi corretti di Entity Framework per il progetto di persistenza del servizio o del modulo selezionato. In un servizio modulare, la migration rimane isolata nel modulo corrispondente, evitando di mescolare modifiche provenienti da contesti diversi.
- Una nuova migrazione del database associata alla versione attuale del servizio;
- Lo script SQL corrispondente, organizzato nel livello di persistenza, in un percorso con versione come /scripts//;
- Artefatti compatibili con la struttura Infrastructure/Persistence del servizio o modulo selezionato;
- Cronologia tracciabile per mettere in relazione la versione del servizio, le modifiche allo schema e il rilascio dell'applicazione.
Passaggio 3: elenco e applicazione delle migrazioni
Prima di applicare le modifiche a un database, elencare le migrazioni note e confermare che la migrazione prevista sia presente:
lino database migrations list --service <ServiceName> --module <ModuleName>
Per applicare le migrazioni all'ambiente configurato:
lino database migrations apply --service <ServiceName> --module <ModuleName>
Nello sviluppo locale, questo flusso accelera la convalida del modello. In ambienti condivisi o di produzione, applica le migrazioni attraverso il processo di distribuzione definito dal team, con revisione, approvazione e backup degli script quando necessario.
Fase 4: inversione o rimozione in ambiente controllato
Utilizzo revert quando Γ¨ necessario restituire una migrazione effettuata in un ambiente controllato, tenendo presente che l'operazione puΓ² eseguire comandi distruttivi a seconda del contenuto della migrazione:
lino database migrations revert --service <ServiceName> --module <ModuleName>
Utilizzo remove per eliminare l'ultima migrazione non confermata, in genere prima di confermare o pubblicare la modifica:
lino database migrations remove --service <ServiceName> --module <ModuleName>
Buone pratiche
- Crea migrazioni ogni volta che vengono apportate modifiche al modello persistente: nuove entitΓ , proprietΓ , relazioni, indici, vincoli, tabelle di autenticazione o tabelle Outbox.
- Esamina il codice generato e l'SQL prima di applicarlo agli ambienti condivisi.
- Prestare particolare attenzione alle ridenominazioni, alle modifiche del tipo, all'eliminazione delle colonne, alle modifiche delle chiavi, alle modifiche dello schema e alle operazioni che possono causare la perdita di dati.
- Mantieni la versione del servizio allineata con gli script generati per facilitare il controllo, il rollback pianificato e la comunicazione sul rilascio.
- Dopo aver creato la migrazione, esegui la compilazione e i test pertinenti per confermare che dominio, persistenza, API e pagine generate rimangano coerenti.
Seguendo questo flusso, il database rimane coerente con il modello di dominio definito in Lino e ogni modifica dello schema Γ¨ documentata, tracciabile e pronta per essere rivista prima della distribuzione.
Passaggio 5: Validazione locale dell'applicazione
Con progetto, Web App, servizi, moduli, entitΓ , migrations, APIs, Commands e Queries pronti, validare l'applicazione prima di generare immagini Docker. Prima, compilare la soluzione per confermare che tutti i progetti, contratti e client generati siano ancora coerenti:
Poi eseguire l'applicazione tramite l'AppHost di Aspire:
dotnet run --project src/Aspire/AppHost/<ProjectName>.AppHost.csproj
Usare il dashboard di Aspire per verificare che APIs, Web App, database, cache, messaggistica e Background Jobs siano stati avviati correttamente. Poi testare i flussi principali nel Backoffice: pagine generate, chiamate Blazor ai progetti Api.Client, migrations applicate, autenticazione quando abilitata, ed eventi o jobs quando fanno parte dello scenario.
Quando l'applicazione compila, viene eseguita localmente e i flussi principali sono validati, il progetto Γ¨ pronto per la fase di packaging.
Generazione di immagini Docker
Dopo che l'applicazione compila, viene eseguita localmente tramite l'AppHost e i flussi principali sono stati testati, Γ¨ possibile generare immagini Docker dei servizi e delle applicazioni web per una successiva pubblicazione in un registro di container.
Usare lino build quando gli elementi selezionati sono pronti per essere confezionati come immagini.
IL Lino CLI semplifica questo processo con il comando:
Una volta eseguito, vedrai un elenco di tutti i servizi e le applicazioni web disponibili nel progetto, insieme alle loro versioni attuali:
Select the services or web applications you want to include in the build:
> [ ] Services
[ ] Catalog |0.1.0|
[ ] Sales |0.1.0|
[ ] Security |0.1.0|
[ ] Stock |0.1.0|
[ ] Web applications
[ ] Backoffice |0.1.0|
Puoi selezionare uno o piΓΉ servizi e applicazioni web per generare immagini contemporaneamente. Basta contrassegnare gli articoli desiderati.
Ti verrΓ quindi chiesto di scegliere come aggiornare la versione delle immagini generate. Le opzioni disponibili sono:
- Mantieni la versione corrente β non modifica la versione esistente;
- Toppa β incrementa la versione della patch (es.: 0.1.0 β 0.1.1);
- Minore β incrementa la versione minore (es.: 0.1.0 β 0.2.0);
- Maggiore β incrementa la versione major (es: 0.1.0 β 1.0.0).
Dopo aver selezionato i servizi e definito l'incremento di versione, il file Lino CLI esegue:
- Costruisci il codice per ogni servizio e applicazione web;
- Generazione dell'immagine Docker corrispondente;
- Applicazione del tag con la versione definita;
- Rendere le immagini disponibili per la pubblicazione nel registro dei contenitori;
- Utilizzando parametri di pubblicazione come
-c Release, -p:PublishProfile=DefaultContainer, -p:ContainerRepository, -p:ContainerImageTag E -p:ContainerLabelVersion, a seconda del tipo di progetto generato.
Al termine del processo, considerando che tutti i servizi e le applicazioni web sono stati selezionati, le immagini generate avranno la seguente struttura:
- mia-app/servizi/catalog-host - tag: 0.1.0
- mia-app/servizi/sales-api - tag: 0.1.0
- mia-app/servizi/security-api - tag: 0.1.0
- mia-app/servizi/stock-api - tag: 0.1.0
- mia-app/webapps/backoffice - tag: 0.1.0
In generale, i servizi semplici tendono a generare repository come project-name/services/service-name-api:1.2.3, i servizi modulari utilizzano gli host come project-name/services/service-name-host:1.2.3e le applicazioni Blazor utilizzano percorsi come project-name/webapps/webapp-name:1.2.3.
Osservazione: Questo processo garantisce coerenza tra il codice e la versione delle immagini Docker, facilitando la distribuzione e la manutenzione di piΓΉ ambienti, oltre a consentire di isolare ciascun servizio in contenitori indipendenti.
Dopo aver generato l'immagine locale, pubblicala nel registro utilizzato dalla piattaforma di distribuzione, ad esempio Docker Hub, GitHub Container Registry, AWS ECR, Azure Container Registry o un altro registro conforme a OCI. Non includere segreti, stringhe di connessione di produzione o credenziali all'interno dell'immagine.
Creazione di versioni nell'applicazione
Lino mantiene la versione operativa di ciascun servizio in src/Services/<ServiceName>/version.txt e ogni applicazione web in src/WebApps/<WebAppName>/version.txt. CiΓ² consente di pianificare rilasci indipendenti per ciascun elemento distribuibile.
Prima di modificare le versioni, controlla lo stato attuale:
Utilizzo lino version show quando hai bisogno di consultare un servizio o un'applicazione web specifica.
L'incremento di nuove versioni di servizi Web o applicazioni Γ¨ un processo semplice e centralizzato. Lino CLI. Basta eseguire il comando:
Proprio come quando si generano immagini Docker, quando esegui questo comando vedrai un elenco completo di tutti i servizi e le applicazioni web nel tuo progetto.
Solo gli elementi selezionati avranno la loro versione aumentata, mentre il resto rimarrΓ invariato.
Select the services or web applications that will have version changes:
> [ ] Services
[ ] Catalog |0.1.0|
[ ] Sales |0.1.0|
[ ] Security |0.1.0|
[ ] Stock |0.1.0|
[ ] Web applications
[ ] Backoffice |0.1.0|
Dopo aver selezionato le voci desiderate, ti verrΓ chiesto di scegliere il tipo di incremento di versione. Le opzioni disponibili sono:
- Toppa β piccole correzioni senza impatto funzionale;
- Minore β aggiunta di nuove funzionalitΓ compatibili con le versioni precedenti;
- Maggiore β modifiche che potrebbero interrompere la compatibilitΓ con le versioni precedenti.
Γ importante evidenziare che le versioni dei servizi e delle applicazioni web hanno un impatto diretto su:
- I tag immagine Docker;
- Le cartelle utilizzate per archiviare gli script generati dalle migrazioni del database;
- Controllo dei rilasci e della cronologia del progetto;
- Note sulla versione, manifesti di distribuzione e comunicazione con i consumatori API.
Prima di applicare un bump, esamina le modifiche al codice, le migrazioni, gli eventi di integrazione, i contratti API e le modifiche al frontend che fanno parte della versione. Una versione Toppa deve rappresentare correzioni compatibili, Minore deve rappresentare aggiunte compatibili, e Maggiore dovrebbe essere riservato ai cambiamenti che richiedono ai consumatori di adattarsi.
Con questo concludiamo la guida passo passo a tutti i comandi essenziali per costruire un progetto web utilizzando Lino CLI, dall'installazione e creazione di servizi, entitΓ , eventi e pagine fino alla generazione di immagini Docker e al versionamento.
Il flusso completo Γ¨ tracciabile: modellazione del dominio, generazione di casi d'uso e schermate, convalida con build e test, creazione di migrazioni, pubblicazione di immagini con tag di versione e rilascio di ciascun servizio o applicazione Web con un valore SemVer esplicito.
Non dimenticare di seguire il nostro canale su YouTube per seguire tutorial dettagliati, dimostrazioni pratiche e consigli sull'utilizzo dello strumento, dalle operazioni semplici alle funzionalitΓ avanzate.