Criando uma Aplicação .NET Completa com o Lino: Guia Passo a Passo
Este tΓ³pico apresenta um guia prΓ‘tico e orientado por passos para usar o Lino CLI como ferramenta principal na construΓ§Γ£o de um projeto: desde a instalaΓ§Γ£o e configuraΓ§Γ£o inicial, passando pela geraΓ§Γ£o de serviΓ§os, mΓ³dulos e entidades, atΓ© recursos avanΓ§ados como eventos, jobs em background, migraΓ§Γ΅es, build de imagens Docker e versionamento.
O objetivo Γ© mostrar, de forma integrada, como os comandos do CLI se encaixam no fluxo de desenvolvimento real β nΓ£o apenas listΓ‘-los, mas explicar o porquΓͺ de cada escolha, o que Γ© gerado automaticamente e quais sΓ£o as implicaΓ§Γ΅es arquiteturais.
Mesmo que cada comando jΓ‘ tenha documentaΓ§Γ£o especΓfica, aqui vocΓͺ verΓ‘ o processo fim-a-fim β um roteiro reproduzΓvel que economiza horas de trabalho repetitivo e ajuda a manter um cΓ³digo consistente e testΓ‘vel.
Ao longo do guia, explicaremos conceitos tΓ©cnicos aplicados pelo Lino (ex.: CQRS, TypedResults, Source Generators, Outbox Pattern), mostraremos exemplos de comandos e indicaremos boas prΓ‘ticas para versionamento, deploy e integraΓ§Γ£o contΓnua.
Use este roteiro como uma sequΓͺncia de aprendizado: primeiro entenda a estrutura, depois modele o domΓnio, sΓ³ entΓ£o gere APIs, pΓ‘ginas, eventos e artefatos de deploy. Isso reduz retrabalho e mantΓ©m o cΓ³digo gerado alinhado ao desenho do sistema.
Instalando e configurando o Lino CLI
O primeiro passo para comeΓ§ar a trabalhar com o Lino CLI Γ© instalar a ferramenta em seu ambiente de desenvolvimento.
Ela Γ© distribuΓda como uma dotnet global tool, o que significa que estarΓ‘ disponΓvel para qualquer projeto .NET no seu computador.
Antes de instalar, confirme que o SDK do .NET exigido pelos templates atuais estΓ‘ disponΓvel, que o terminal consegue executar dotnet e que o diretΓ³rio de ferramentas globais do .NET estΓ‘ no PATH.
Passo 1: InstalaΓ§Γ£o
Para instalar (ou atualizar) o Lino CLI, execute o seguinte comando no terminal:
dotnet tool install --global Tolitech.Lino
ObservaΓ§Γ΅es importantes:
- Se jΓ‘ houver uma versΓ£o instalada, vocΓͺ pode usar
dotnet tool update --global Tolitech.Linopara atualizar. - Verifique se o diretΓ³rio de ferramentas globais do .NET estΓ‘ no
PATHdo sistema para que o comandolinofuncione corretamente.
Passo 2: Configurar idioma
ApΓ³s a instalaΓ§Γ£o, Γ© recomendado configurar o idioma (ou cultura) que o CLI irΓ‘ utilizar em mensagens, prompts e logs:
lino preferences culture set
VocΓͺ serΓ‘ solicitado a escolher entre os idiomas disponΓveis. Essa configuraΓ§Γ£o garante que todas as instruΓ§Γ΅es e prompts apareΓ§am de forma consistente no idioma desejado. Essa preferΓͺncia altera mensagens, prompts e orientaΓ§Γ΅es localizadas da CLI; ela nΓ£o renomeia entidades, serviΓ§os, mΓ³dulos ou termos de negΓ³cio gerados no projeto.
Passo 3: AutenticaΓ§Γ£o e registro
Para acessar todos os recursos do Lino, incluindo templates avanΓ§ados, publicaΓ§Γ£o de imagens Docker e integraΓ§Γ΅es com serviΓ§os externos, Γ© necessΓ‘rio estar autenticado.
- Caso ainda nΓ£o possua cadastro, registre-se com o comando:
lino user register
- Caso jΓ‘ tenha cadastro, faΓ§a login com:
lino auth login
O que acontece: o CLI armazena um token de autenticaΓ§Γ£o localmente, permitindo que vocΓͺ execute comandos que requerem acesso a recursos protegidos sem precisar se logar a cada uso. Mantenha esse token privado e evite compartilhar o mesmo perfil de usuΓ‘rio entre desenvolvedores, agentes de CI ou mΓ‘quinas diferentes.
Passo 4: VerificaΓ§Γ£o
Para confirmar que a instalaΓ§Γ£o e autenticaΓ§Γ£o foram realizadas com sucesso, execute:
lino --version
Se o comando retornar a versΓ£o instalada, vocΓͺ estΓ‘ pronto para comeΓ§ar a utilizar o Lino CLI em seus projetos.
Criando o projeto MyApp
Neste passo, vamos criar a estrutura inicial do projeto utilizando o Lino CLI. Este projeto servirΓ‘ como base para demonstrar a criaΓ§Γ£o de serviΓ§os, mΓ³dulos, front-end e toda a integraΓ§Γ£o de eventos. Um projeto Lino nΓ£o Γ© apenas uma pasta com uma solution: ele define convenΓ§Γ΅es para fronteiras de serviΓ§o, bibliotecas compartilhadas, host Aspire, estrutura de frontend, testes, gerenciamento de pacotes, analyzers e configuraΓ§Γ΅es que os prΓ³ximos comandos reutilizam.
Passo 1: Executando o comando de criaΓ§Γ£o
Para criar um novo projeto, execute o comando abaixo no terminal:
lino project new
O CLI irΓ‘ guiΓ‘-lo passo a passo, solicitando informaΓ§Γ΅es como:
- Nome do projeto: usaremos
MyApp, mas vocΓͺ pode escolher qualquer nome que desejar; - Recursos adicionais: analisadores de cΓ³digo, cache distribuΓdo, suporte a eventos assΓncronos, etc.
Passo 2: Configurando recursos essenciais
Para este projeto, recomendamos habilitar os seguintes recursos desde o inΓcio:
- Analisadores de cΓ³digo: para garantir que o cΓ³digo esteja seguindo boas prΓ‘ticas e padrΓ΅es consistentes, prevenindo erros comuns de implementaΓ§Γ£o;
- Cache distribuΓdo: melhora a performance da aplicaΓ§Γ£o em cenΓ‘rios com mΓΊltiplos serviΓ§os, evitando consultas desnecessΓ‘rias ao banco de dados;
- ComunicaΓ§Γ£o assΓncrona: habilita o uso de eventos e filas para integraΓ§Γ£o entre serviΓ§os, garantindo escalabilidade e desacoplamento.
Γ importante habilitar todas essas opΓ§Γ΅es neste projeto, pois criaremos mΓΊltiplos serviΓ§os que irΓ£o se comunicar atravΓ©s de eventos de integraΓ§Γ£o. Isso permitirΓ‘ que vocΓͺ compreenda como estruturar sistemas modulares e distribuΓdos usando o Lino.
Passo 3: Estrutura gerada
ApΓ³s a execuΓ§Γ£o do comando e configuraΓ§Γ£o dos recursos, o CLI irΓ‘ gerar a estrutura inicial do projeto. Ela incluirΓ‘:
- Pastas de serviΓ§os e mΓ³dulos;
- Templates para front-end (se aplicΓ‘vel);
- ConfiguraΓ§Γ΅es iniciais de cache, eventos e integraΓ§Γ΅es;
- Arquivos de soluΓ§Γ£o (.slnx) e projeto (.csproj) prontos para compilaΓ§Γ£o.
Agora seu projeto MyApp estΓ‘ pronto para receber os serviΓ§os, mΓ³dulos, entidades e front-end que configuraremos nos prΓ³ximos passos.
Antes de continuar, abra a soluΓ§Γ£o gerada e execute dotnet build para confirmar que referΓͺncias, source generators, templates, arquivos de projeto e configuraΓ§Γ£o inicial estΓ£o coerentes.
Adicionando a aplicaΓ§Γ£o web Backoffice
Um sistema completo normalmente precisa de pelo menos uma aplicaΓ§Γ£o web para operar o domΓnio. Neste guia, a aplicaΓ§Γ£o se chama Backoffice e representa uma interface interna para administradores, gestores ou usuΓ‘rios operacionais acompanharem produtos, categorias, estoques, vendas e demais informaΓ§Γ΅es do sistema.
A aplicaΓ§Γ£o web nΓ£o substitui os serviΓ§os de domΓnio. Ela atua como ponto de entrada visual para consumir APIs, acionar Commands, consultar Queries e expor telas coerentes com as regras jΓ‘ modeladas nos serviΓ§os.
Passo 1: Executando o comando de criaΓ§Γ£o
Para adicionar uma nova aplicaΓ§Γ£o web ao projeto, utilize:
lino web-app new
O alias lino webapp new tambΓ©m estΓ‘ disponΓvel para facilitar a digitaΓ§Γ£o. Durante a execuΓ§Γ£o, informe um nome claro para a aplicaΓ§Γ£o web; neste exemplo, usaremos Backoffice.
lino web-app new --name Backoffice
Passo 2: Entendendo a estrutura gerada
Ao final do processo, o Lino cria a estrutura inicial da Web App em src/WebApps/<WebAppName>. Para uma aplicaΓ§Γ£o Blazor, a estrutura pode incluir projetos server/client, recursos compartilhados, arquivos de localizaΓ§Γ£o, clients para consumo das APIs e convenΓ§Γ΅es que serΓ£o usadas posteriormente por lino page new.
- Pastas para pΓ‘ginas, componentes, layouts, services e recursos da aplicaΓ§Γ£o;
- Clientes HTTP e contratos necessΓ‘rios para consumir APIs expostas pelos serviΓ§os do projeto;
- Resources de localizaΓ§Γ£o e templates iniciais usados pela experiΓͺncia web;
- Projetos client/server quando o tipo de aplicaΓ§Γ£o exigir essa separaΓ§Γ£o;
- ConvenΓ§Γ΅es de rotas, navegaΓ§Γ£o e integraΓ§Γ£o que serΓ£o reutilizadas na geraΓ§Γ£o de pΓ‘ginas;
- Pontos de integraΓ§Γ£o com autenticaΓ§Γ£o e autorizaΓ§Γ£o quando a feature de auth for adicionada ao projeto.
Passo 3: Quando criar a Web App no fluxo
Se vocΓͺ jΓ‘ sabe que o sistema terΓ‘ uma interface Blazor, crie a Web App logo no inΓcio, depois da criaΓ§Γ£o do projeto. Assim, os serviΓ§os, mΓ³dulos, entidades, APIs e pΓ‘ginas gerados depois jΓ‘ ficam alinhados com a aplicaΓ§Γ£o web que irΓ‘ consumi-los.
Esse fluxo Γ© especialmente ΓΊtil porque os serviΓ§os criados posteriormente tambΓ©m geram projetos tipados de Api.Contracts e Api.Client, consumidos pelo projeto Blazor. Com a Web App presente desde cedo, fica mais simples validar o caminho completo: domΓnio, API, contratos, HttpClient e tela.
ObservaΓ§Γ΅es importantes
- O Backoffice deve consumir os dados por meio das APIs geradas, mantendo a lΓ³gica de negΓ³cio nos serviΓ§os e mΓ³dulos corretos.
- Antes de expor pΓ‘ginas administrativas, revise autenticaΓ§Γ£o, autorizaΓ§Γ£o, roles, permissΓ΅es e polΓticas de acesso.
- VocΓͺ pode criar mΓΊltiplas aplicaΓ§Γ΅es web, por exemplo um
Backofficeinterno e umSitepΓΊblico, quando pΓΊblicos, permissΓ΅es, deploys ou responsabilidades forem diferentes. - Evite misturar fluxos pΓΊblicos e administrativos na mesma Web App quando isso dificultar seguranΓ§a, navegaΓ§Γ£o, deploy ou ownership da equipe.
Com a aplicaΓ§Γ£o web criada, o guia pode avanΓ§ar para os serviΓ§os e mΓ³dulos que fornecerΓ£o os dados e regras de negΓ³cio consumidos por essa interface.
Criando serviΓ§os e mΓ³dulos
Nesta etapa, vamos construir os serviΓ§os e mΓ³dulos que irΓ£o compor a aplicaΓ§Γ£o. O objetivo Γ© criar uma arquitetura modular e escalΓ‘vel, permitindo que diferentes Γ‘reas do sistema, como produtos, categorias, estoque, vendas e mΓdia, evoluam de forma independente, mantendo coesΓ£o e facilitando a manutenΓ§Γ£o. ServiΓ§os definem fronteiras de deploy e persistΓͺncia; mΓ³dulos organizam Γ‘reas de negΓ³cio dentro de um serviΓ§o modular. Antes de criar arquivos, avalie quais partes do domΓnio precisam de banco prΓ³prio, release independente, contrato de integraΓ§Γ£o ou ownership separado.
Passo 1: Definindo os serviΓ§os
Inicialmente, criaremos os seguintes serviΓ§os, cada um com responsabilidades bem definidas:
- Catalog (modular) β responsΓ‘vel por gerenciar produtos, categorias e preΓ§os;
- Sales β responsΓ‘vel pelo processamento de vendas e pedidos;
- Stock β responsΓ‘vel pelo gerenciamento de estoques e movimentaΓ§Γ΅es;
- Security β responsΓ‘vel por autenticaΓ§Γ£o, autorizaΓ§Γ£o e gerenciamento de usuΓ‘rios.
Para criar os serviΓ§os do exemplo, execute um comando para cada serviΓ§o. No wizard do Catalog, escolha arquitetura modular; nos demais, escolha a arquitetura adequada para uma fronteira simples.
lino service new --name Catalog lino service new --name Sales lino service new --name Stock lino service new --name Security
Durante a execuΓ§Γ£o do comando, o CLI irΓ‘ solicitar:
- Nome do serviΓ§o: por exemplo,
Catalog; - Nome de exibiΓ§Γ£o e estilo de arquitetura: escolha uma arquitetura simples para fronteiras compactas ou modular quando o serviΓ§o tiver Γ‘reas coesas independentes;
- Banco de dados: escolha a tecnologia que se adequa melhor ao seu projeto (SQL Server, PostgreSQL, etc.);
Passo 2: Criando mΓ³dulos dentro de serviΓ§os
Nem todos os serviΓ§os precisam ser modulares. No nosso projeto, apenas o serviΓ§o Catalog terΓ‘ mΓ³dulos, para separar responsabilidades como merchandising e precificaΓ§Γ£o.
Definimos para o serviΓ§o Catalog os seguintes mΓ³dulos:
- Merchandising β gerenciamento de produtos e categorias;
- Pricing β gerenciamento de preΓ§os, promoΓ§Γ΅es e histΓ³rico de alteraΓ§Γ΅es.
Para criar os mΓ³dulos do Catalog, execute:
lino module new --service Catalog --name Merchandising lino module new --service Catalog --name Pricing
VocΓͺ pode criar quantos mΓ³dulos desejar dentro do serviΓ§o modular Catalog. AlΓ©m disso, dependendo da complexidade, alguns mΓ³dulos poderiam se tornar serviΓ§os independentes futuramente. A separaΓ§Γ£o apresentada aqui Γ© apenas didΓ‘tica e serve como exemplo de organizaΓ§Γ£o modular. NΓ£o use mΓ³dulos apenas para criar pastas; use-os quando eles protegem uma Γ‘rea de negΓ³cio com entidades, casos de uso, APIs, migrations e eventos prΓ³prios.
Estrutura final do projeto
ApΓ³s a criaΓ§Γ£o dos serviΓ§os e mΓ³dulos, sua soluΓ§Γ£o deverΓ‘ ter uma estrutura semelhante Γ seguinte:
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/
ExplicaΓ§Γ£o da estrutura:
Services/: contΓ©m todos os serviΓ§os do sistema, cada um isolado com sua prΓ³pria lΓ³gica de negΓ³cio, infraestrutura e hospedagem;Modules/: pastas dentro de serviΓ§os modulares, permitindo organizar funcionalidades especΓficas e manter cΓ³digo coeso;WebApps/: frontends associados ao sistema, jΓ‘ integrados aos serviΓ§os;Shared/: bibliotecas e recursos compartilhados entre serviΓ§os e frontends;tests/: testes unitΓ‘rios e de integraΓ§Γ£o organizados por serviΓ§o e mΓ³dulo.
Com essa estrutura modular, cada equipe ou desenvolvedor pode trabalhar de forma independente em diferentes partes do sistema, facilitando escalabilidade, manutenΓ§Γ£o e testes.
Depois de criar serviΓ§os e mΓ³dulos, execute dotnet build para confirmar que os projetos foram anexados corretamente Γ soluΓ§Γ£o, ao host Aspire, aos projetos compartilhados e Γ estrutura de testes.
Adicionando autenticaΓ§Γ£o e autorizaΓ§Γ£o
A autenticaΓ§Γ£o e autorizaΓ§Γ£o sΓ£o elementos essenciais de qualquer sistema moderno. AutenticaΓ§Γ£o comprova quem Γ© o usuΓ‘rio; autorizaΓ§Γ£o define o que esse usuΓ‘rio pode executar. No Lino CLI, a feature de auth gera a base necessΓ‘ria para usuΓ‘rios, papΓ©is, permissΓ΅es, tokens, polΓticas de acesso e integraΓ§Γ£o com APIs.
Passo 1: Executando o comando de autenticaΓ§Γ£o
Para adicionar os recursos de autenticaΓ§Γ£o e autorizaΓ§Γ£o, utilize o comando:
lino feature auth add
O CLI irΓ‘ guiΓ‘-lo pelas seguintes etapas:
- Escolha do serviΓ§o ou mΓ³dulo: vocΓͺ precisa indicar onde os artefatos de autenticaΓ§Γ£o serΓ£o instalados. No nosso projeto de exemplo, utilizamos o serviΓ§o Security, que centraliza toda a lΓ³gica de seguranΓ§a do sistema;
- ConfiguraΓ§Γ΅es adicionais: criaΓ§Γ£o de tabelas de usuΓ‘rios, papΓ©is, permissΓ΅es, tokens e configuraΓ§Γ£o de polΓticas de acesso;
- Tempo de vida dos tokens: definiΓ§Γ£o de expiraΓ§Γ£o para access token e refresh token de acordo com a polΓtica de seguranΓ§a do produto;
- Tipo do identificador do usuΓ‘rio: escolha do tipo usado pelo modelo de usuΓ‘rio e pelos contratos gerados.
Passo 2: Estrutura gerada
ApΓ³s a execuΓ§Γ£o do comando, o serviΓ§o Security conterΓ‘ arquivos e pastas como:
- Domain/Entities: agregados, entidades e regras para usuΓ‘rios, papΓ©is, permissΓ΅es e tokens;
- Infrastructure/Persistence: configuraΓ§Γ΅es do banco de dados, mapeamentos do Entity Framework e migrations para tabelas de seguranΓ§a;
- Application: Commands, Queries, Handlers, serviΓ§os de autenticaΓ§Γ£o, geraΓ§Γ£o de tokens, validaΓ§Γ£o de credenciais e checagens de permissΓ£o;
- API/Host: endpoints para login, logout, cadastro, refresh token e operaΓ§Γ΅es protegidas;
- IntegraΓ§Γ£o com Web App: suporte para fluxos autenticados quando uma aplicaΓ§Γ£o web estiver presente.
Com isso, sua aplicaΓ§Γ£o terΓ‘ autenticaΓ§Γ£o robusta e controle de acesso granular, pronta para suportar mΓΊltiplos usuΓ‘rios e diferentes nΓveis de permissΓ΅es. Ainda assim, cΓ³digo gerado deve ser tratado como uma base forte, nΓ£o como a revisΓ£o final de seguranΓ§a. Antes de produΓ§Γ£o, revise tempo de vida de tokens, desenho de permissΓ΅es, polΓtica de senha, HTTPS, secrets, rate limiting, logs e configuraΓ§Γ΅es de deploy.
Adicionando Background Jobs
Em sistemas distribuΓdos e modulares, como o que estamos construindo com o Lino CLI, nem todos os serviΓ§os se comunicam diretamente entre si. Para garantir consistΓͺncia e confiabilidade na troca de informaΓ§Γ΅es, utilizamos eventos de integraΓ§Γ£o. PorΓ©m, para processar esses eventos de forma eficiente e assΓncrona, precisamos de Background Jobs.
O Lino utiliza o padrΓ£o Outbox Pattern para garantir que todas as mensagens geradas pelos serviΓ§os sejam registradas de forma confiΓ‘vel antes de serem enviadas. Com isso, conseguimos:
- Evitar a perda de eventos em caso de falhas ou reinicializaΓ§Γ΅es do serviΓ§o;
- Garantir que a mesma mensagem seja enviada apenas uma vez;
- Permitir o reprocessamento de mensagens em caso de falha na entrega;
- Separar o processamento de eventos da lΓ³gica principal da aplicaΓ§Γ£o, melhorando performance e escalabilidade.
Passo 1: Executando o comando
Para adicionar suporte a Background Jobs no seu projeto, execute o comando:
lino feature background-job add
O CLI irΓ‘ solicitar que vocΓͺ selecione o serviΓ§o onde o Background Job serΓ‘ instalado. Geralmente, vocΓͺ escolherΓ‘ o serviΓ§o que centraliza a produΓ§Γ£o de eventos, como Catalog ou Sales. Nas opΓ§Γ΅es atuais, o wizard tambΓ©m pode solicitar o mΓ³dulo, a biblioteca de jobs, se eventos de Outbox devem ser processados, o agendamento e o tamanho do lote. O fluxo dos templates atuais usa Hangfire para execuΓ§Γ£o recorrente dos jobs.
Passo 2: Configurando a execuΓ§Γ£o
Durante a configuraΓ§Γ£o, vocΓͺ poderΓ‘ definir:
- Intervalo de verificaΓ§Γ£o: determina com que frequΓͺncia o Background Job irΓ‘ verificar a tabela Outbox para novas mensagens. Um intervalo muito curto pode aumentar o uso de recursos, enquanto um intervalo longo pode atrasar a entrega de eventos;
- Lote de registros processados por vez: controla quantos eventos serΓ£o lidos e enviados por execuΓ§Γ£o. Lotes maiores podem aumentar a performance, mas exigem mais memΓ³ria e processamento;
- PolΓtica de retries: em caso de falha no envio de mensagens, vocΓͺ poderΓ‘ configurar quantas vezes o job tentarΓ‘ reenviar.
Esses parΓ’metros dependem do tamanho do seu sistema, da capacidade da mΓ‘quina e do volume esperado de eventos.
Passo 3: Estrutura gerada
ApΓ³s a configuraΓ§Γ£o, o projeto terΓ‘ um Background Job pronto para processar mensagens das tabelas Outbox em cada serviΓ§o.
- O caso de uso altera o domΓnio e registra um evento de domΓnio ou integraΓ§Γ£o.
- A unidade de trabalho salva os dados de negΓ³cio e as mensagens de Outbox na mesma transaΓ§Γ£o.
- O Hangfire executa jobs recorrentes que leem mensagens pendentes em lotes.
- As mensagens sΓ£o publicadas no mecanismo de integraΓ§Γ£o configurado, como RabbitMQ quando comunicaΓ§Γ£o assΓncrona estiver habilitada.
- Mensagens concluΓdas, falhas, antigas ou presas podem ser tratadas pela lΓ³gica e configuraΓ§Γ£o geradas para o job.
Com isso, vocΓͺ garante que todos os eventos de integraΓ§Γ£o sejam processados de forma confiΓ‘vel e eficiente, permitindo que mΓΊltiplos serviΓ§os e mΓ³dulos se comuniquem de forma assΓncrona, sem impactar a performance do sistema principal. A regra operacional mais importante Γ© manter a fronteira transacional clara: eventos que precisam ser enviados via Outbox devem ser criados no mesmo fluxo transacional da alteraΓ§Γ£o de negΓ³cio que representam.
Criando entidades e enumeraΓ§Γ΅es
Nesta seΓ§Γ£o, vamos detalhar o design das entidades, enumeraΓ§Γ΅es e Value Objects da aplicaΓ§Γ£o, mostrando em quais serviΓ§os e mΓ³dulos cada item serΓ‘ criado.
1. Criando a entidade Category
Para criar a entidade Category no serviΓ§o Catalog e no mΓ³dulo Merchandising, execute:
lino entity new --service Catalog --module Merchandising --name Category
A entidade serΓ‘ criada no serviΓ§o Catalog e no mΓ³dulo Merchandising com a seguinte estrutura:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ β PK β FK β Property name β Type β Length β Required β Auto-increment β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€ β x β β Id β Guid β β x β x β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€ β β β Name β string β 50 β x β β ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
2. Criando a entidade Product
Em seguida, criamos a entidade Product no mesmo serviΓ§o e mΓ³dulo. Neste fluxo, o Value Object ProductDimension e a enum ProductStatus sΓ£o configurados dentro do prΓ³prio wizard de criaΓ§Γ£o da entidade, como parte do agregado Product:
lino entity new --service Catalog --module Merchandising --name Product
Durante a execuΓ§Γ£o, adicione as propriedades simples, o relacionamento com Category, a propriedade Dimensions do tipo Value Object e a propriedade Status do 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 Configurando o Value Object ProductDimension dentro de Product
No cenΓ‘rio deste guia, ProductDimension nΓ£o Γ© criado por um comando separado. Ele Γ© adicionado durante o lino entity new de Product, como a propriedade Dimensions, e representa as dimensΓ΅es do produto:
βββββββββββββββββ¬ββββββββββ¬βββββββββ¬βββββββββββ β Property name β Type β Length β Required β βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€ β Width β decimal β β x β βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€ β Height β decimal β β x β βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€ β Depth β decimal β β x β βββββββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββ
ObservaΓ§Γ£o: o comando lino value-object new existe para cenΓ‘rios em que o Value Object precisa ser criado separadamente. Nesses casos, use os argumentos do serviΓ§o e do mΓ³dulo de destino:
lino value-object new --service <ServiceName> --module <ModuleName> --name <ValueObjectName>
2.2 Configurando a Enum ProductStatus dentro de Product
Da mesma forma, ProductStatus Γ© configurada dentro do lino entity new de Product, como a propriedade Status. Ela define o status do produto:
βββββββββ¬βββββββββββββββ¬βββββββββββββββ β Value β Name β Display Name β βββββββββΌβββββββββββββββΌβββββββββββββββ€ β 1 β Active β Active β βββββββββΌβββββββββββββββΌβββββββββββββββ€ β 2 β Inactive β Inactive β βββββββββΌβββββββββββββββΌβββββββββββββββ€ β 3 β Discontinued β Discontinued β βββββββββ΄βββββββββββββββ΄βββββββββββββββ
ObservaΓ§Γ£o: o comando lino enumeration new tambΓ©m pode ser usado quando uma enum precisa ser criada separadamente em outro cenΓ‘rio:
lino enumeration new --service <ServiceName> --module <ModuleName> --name <EnumerationName>
3. Adicionando novas propriedades
Com a evoluΓ§Γ£o do projeto, podemos editar entidades existentes para adicionar novas propriedades.
Por exemplo, adicionaremos uma lista de imagens Γ entidade Product:
lino entity edit --service Catalog --module Merchandising --entity Product
Dentro desse mesmo fluxo, criamos a propriedade Images do tipo List<ProductImage>. Como ProductImage pertence ao agregado Product, sua estrutura tambΓ©m Γ© configurada durante o lino entity edit de 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<ProductImage> β β β β ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββββββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
3.1 Configurando ProductImage dentro de Product
ProductImage nΓ£o Γ© criado por um comando separado neste cenΓ‘rio. Ele Γ© configurado como item da coleΓ§Γ£o Images durante a ediΓ§Γ£o de Product e possui a seguinte estrutura:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ β PK β FK β Property name β Type β Length β Required β Auto-increment β ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€ β x β β Id β Guid β β x β x β ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€ β β x β ProductId β EntityId β β x β β ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€ β β β UploadDate β DateTimeOffset β β x β β ββββββΌβββββΌββββββββββββββββΌβββββββββββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€ β β β Image β File β β x β β ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
ObservaΓ§Γ£o: o comando lino entity new existe para criar entidades independentes em outros cenΓ‘rios. Quando a entidade nΓ£o faz parte da ediΓ§Γ£o de um agregado existente, use:
lino entity new --service <ServiceName> --module <ModuleName> --name <EntityName>
4. Criando entidades para outros serviΓ§os
No serviΓ§o Sales, criamos a entidade ProductSnapshot, que serΓ‘ alimentada pelos eventos de integraΓ§Γ£o.
Como o Id original da entidade Product vem do serviΓ§o Catalog, ele nΓ£o pode ser auto-incremental aqui.
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 β β ββββββ΄βββββ΄ββββββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
ObservaΓ§Γ£o: apenas os campos essenciais foram replicados no ProductSnapshot para o serviΓ§o Sales. Entidades complementares, como Customer, Order e StockItem, nΓ£o serΓ£o detalhadas aqui para simplificar a documentaΓ§Γ£o.
O ProductSnapshot funciona como uma shadow entity: uma cΓ³pia local, mΓnima e controlada de dados cujo dono estΓ‘ em outro serviΓ§o. Isso permite que Sales consulte os dados necessΓ‘rios de produto sem depender diretamente da entidade ou do banco do Catalog.
Esse tipo de estrutura tambΓ©m poderia ser criado pelo comando lino shadow new, alias de lino shadow-entity new. Nesse fluxo, o Lino copia a estrutura de uma entidade de outro serviΓ§o ou mΓ³dulo e permite selecionar apenas as propriedades que fazem sentido para o contexto consumidor.
lino shadow new --service <ServiceName> --module <ModuleName> --name <ShadowEntityName>
No exemplo, a entidade de origem Γ© Catalog.Merchandising.Product e o destino Γ© o serviΓ§o Sales, mantendo somente os campos necessΓ‘rios para vendas.
Criando eventos e seus manipuladores
Recapitulando, no tΓ³pico anterior criamos no serviΓ§o modular Catalog.Merchandising as entidades Product, Category e ProductImage, enquanto no serviΓ§o Sales criamos a entidade ProductSnapshot.
Agora, vamos criar eventos de domΓnio e eventos de integraΓ§Γ£o. O objetivo Γ© que, ao criar ou atualizar produtos no serviΓ§o Catalog, essas alteraΓ§Γ΅es sejam replicadas para os serviΓ§os consumidores, como Sales e Stock.
1. Criando eventos de domΓnio
O primeiro passo Γ© criar os eventos de domΓnio ProductCreated e ProductUpdated com o comando:
lino event new
Durante a criaΓ§Γ£o, podemos associar o evento a um manipulador e, simultaneamente, configurar o disparo de um evento de integraΓ§Γ£o. Isso centraliza a criaΓ§Γ£o de todo o fluxo necessΓ‘rio.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ β 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 β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
Da mesma forma, criamos o 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 β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
Com isso, temos:
- Eventos de domΓnio criados (
ProductCreatedeProductUpdated); - Manipuladores de eventos de domΓnio correspondentes;
- Eventos de integraΓ§Γ£o registrados na Outbox automaticamente pelo manipulador de eventos de domΓnio.
2. Criando manipuladores de eventos de integraΓ§Γ£o
O prΓ³ximo passo Γ© definir quais serviΓ§os irΓ£o consumir os eventos de integraΓ§Γ£o. Para isso, usamos:
lino event-handler new
O fluxo de criaΓ§Γ£o envolve:
- Selecionar o serviΓ§o, mΓ³dulo e entidade que conterΓ‘ o manipulador;
- Selecionar o evento de integraΓ§Γ£o que serΓ‘ consumido e de qual serviΓ§o/mΓ³dulo/entidade ele virΓ‘.
Por exemplo, no serviΓ§o Sales criamos os manipuladores para ProductCreated e ProductUpdated que irΓ£o consumir os eventos disparados pelo 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 β ββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
Com isso, temos dois manipuladores de eventos de integraΓ§Γ£o no serviΓ§o Sales, consumindo apenas os campos necessΓ‘rios dos eventos de integraΓ§Γ£o do Catalog.Merchandising. Isso garante que as tabelas replicadas mantenham apenas os dados essenciais, otimizando armazenamento e desempenho. Em termos de arquitetura, o fluxo esperado Γ©: o Command Handler altera o agregado, o evento de domΓnio Γ© levantado, o manipulador prepara o evento de integraΓ§Γ£o, a Outbox armazena a mensagem, o Background Job processa a pendΓͺncia e o mecanismo de mensageria entrega a mensagem aos consumidores. Isso evita acoplamento sΓncrono entre serviΓ§os e reduz o risco de o banco ser alterado sem que o evento correspondente seja publicado.
Gerando pΓ‘ginas web, APIs, Commands e Queries
Uma das grandes vantagens do Lino CLI Γ© permitir a criaΓ§Γ£o integrada de pΓ‘ginas web, APIs, Commands e Queries de forma automatizada, simplificando todo o fluxo de desenvolvimento. Quando o modelo de domΓnio jΓ‘ estΓ‘ estΓ‘vel o suficiente, esse comando cria um caminho completo da tela atΓ© a persistΓͺncia, tornando visΓvel para o usuΓ‘rio final o trabalho de modelagem feito nas etapas anteriores. Para iniciar, basta executar o comando:
lino page new
Durante o processo, vocΓͺ irΓ‘:
- Selecionar o serviΓ§o, mΓ³dulo e entidade que deseja expor;
- Escolher o tipo e o nome da pΓ‘gina que serΓ‘ gerada;
- Escolher os campos que farΓ£o parte da listagem;
- Gerar automaticamente pΓ‘ginas de listagem (grid paginado) e formulΓ‘rio de criaΓ§Γ£o/ediΓ§Γ£o;
- Gerar classes de HttpClient para consumo pelo frontend;
- Criar contratos de request/response e todas as APIs REST necessΓ‘rias (POST, PUT, PATCH, DELETE e GET);
- Criar Commands, Queries, Handlers e validators, que vΓ£o atΓ© o banco de dados garantindo o fluxo completo de CRUD.
Com esse comando, vocΓͺ obtΓ©m uma aplicaΓ§Γ£o funcional sem precisar escrever manualmente a camada de interface, APIs e lΓ³gica de negΓ³cio, mantendo o padrΓ£o e a consistΓͺncia entre serviΓ§os. Mesmo assim, revise regras de negΓ³cio e validaΓ§Γ΅es depois da geraΓ§Γ£o, porque nem toda regra pode ser inferida apenas pelos metadados das propriedades.
Para este projeto, podemos gerar as pΓ‘ginas integradas para as seguintes entidades:
- Catalog.Merchandising.
Category - Catalog.Merchandising.
Product - Sales.
ProductSnapshot
ApΓ³s gerar as pΓ‘ginas, APIs e Commands/Queries, a aplicaΓ§Γ£o estarΓ‘ pronta para interagir de forma completa entre frontend e backend, com validaΓ§Γ΅es, rotas e persistΓͺncia jΓ‘ configuradas automaticamente pelo Lino CLI.
Execute dotnet build apΓ³s a geraΓ§Γ£o para identificar cedo referΓͺncias quebradas, contratos inconsistentes ou impactos de mudanΓ§as recentes no modelo.
Criando e aplicando migrations
Depois de criar ou alterar entidades, Value Objects, enumeraΓ§Γ΅es, relacionamentos, autenticaΓ§Γ£o, suporte a tenant ou persistΓͺncia de Background Jobs, gere migrations para manter banco de dados e cΓ³digo alinhados. A migration transforma a mudanΓ§a de modelo em um artefato explΓcito, versionΓ‘vel e revisΓ‘vel.
O Lino CLI coordena esse processo com Entity Framework, selecionando o serviΓ§o/mΓ³dulo correto, usando a versΓ£o atual do serviΓ§o e organizando os scripts gerados para facilitar rastreabilidade.
Passo 1: Criando uma migration
Para criar uma nova migration, execute:
lino database migrations add
O comando tambΓ©m pode aceitar aliases como lino database migrations new e lino database migrations create, mas a forma preferida na documentaΓ§Γ£o Γ© add.
Durante a execuΓ§Γ£o, vocΓͺ deverΓ‘ informar:
- O serviΓ§o que receberΓ‘ a migration, por exemplo
Catalog; - O mΓ³dulo afetado, quando o serviΓ§o for modular, por exemplo
Merchandising; - A versΓ£o atual do serviΓ§o, lida a partir de
src/Services/<ServiceName>/version.txt; - Uma descriΓ§Γ£o objetiva para a migration, como
Initial migrationouAdd 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 vocΓͺ jΓ‘ sabe o serviΓ§o e o mΓ³dulo, pode informar esses dados diretamente:
lino database migrations add --service <ServiceName> --module <ModuleName>
Passo 2: O que Γ© gerado
Ao confirmar a criaΓ§Γ£o, o Lino prepara os comandos corretos do Entity Framework para o projeto de persistΓͺncia do serviΓ§o ou mΓ³dulo selecionado. Em um serviΓ§o modular, a migration permanece isolada no mΓ³dulo correspondente, evitando misturar alteraΓ§Γ΅es de contextos diferentes.
- Uma nova migration de banco de dados associada Γ versΓ£o atual do serviΓ§o;
- O script SQL correspondente, organizado na camada de persistΓͺncia, em um caminho versionado como /scripts/<version>/<nome do arquivo>;
- Artefatos compatΓveis com a estrutura de Infrastructure/Persistence do serviΓ§o ou mΓ³dulo selecionado;
- HistΓ³rico rastreΓ‘vel para relacionar versΓ£o de serviΓ§o, mudanΓ§as de schema e release da aplicaΓ§Γ£o.
Passo 3: Listando e aplicando migrations
Antes de aplicar alteraΓ§Γ΅es em um banco, liste as migrations conhecidas e confirme se a migration esperada estΓ‘ presente:
lino database migrations list --service <ServiceName> --module <ModuleName>
Para aplicar migrations no ambiente configurado:
lino database migrations apply --service <ServiceName> --module <ModuleName>
Em desenvolvimento local, esse fluxo acelera a validaΓ§Γ£o do modelo. Em ambientes compartilhados ou produΓ§Γ£o, aplique migrations pelo processo de deploy definido pela equipe, com revisΓ£o do script, aprovaΓ§Γ£o e backup quando necessΓ‘rio.
Passo 4: Revertendo ou removendo em ambiente controlado
Use revert quando precisar voltar uma migration aplicada em um ambiente controlado, entendendo que a operaΓ§Γ£o pode executar comandos destrutivos dependendo do conteΓΊdo da migration:
lino database migrations revert --service <ServiceName> --module <ModuleName>
Use remove para descartar a ΓΊltima migration ainda nΓ£o consolidada, normalmente antes de commitar ou publicar a alteraΓ§Γ£o:
lino database migrations remove --service <ServiceName> --module <ModuleName>
Boas prΓ‘ticas
- Crie migrations sempre que houver alteraΓ§Γ΅es no modelo persistido: novas entidades, propriedades, relaΓ§Γ΅es, Γndices, constraints, tabelas de auth ou tabelas de Outbox.
- Revise o cΓ³digo e o SQL gerados antes de aplicar em ambientes compartilhados.
- Tenha atenΓ§Γ£o especial com renames, mudanΓ§as de tipo, drops de coluna, alteraΓ§Γ΅es de chave, mudanΓ§as de schema e operaΓ§Γ΅es que podem causar perda de dados.
- Mantenha a versΓ£o do serviΓ§o alinhada aos scripts gerados para facilitar auditoria, rollback planejado e comunicaΓ§Γ£o de release.
- Depois de criar a migration, execute build e testes relevantes para confirmar que domain, persistence, APIs e pΓ‘ginas geradas continuam coerentes.
Seguindo esse fluxo, o banco de dados permanece consistente com o modelo de domΓnio definido no Lino, e cada mudanΓ§a de schema fica documentada, rastreΓ‘vel e pronta para ser revisada antes do deploy.
Passo 5: Validando a aplicaΓ§Γ£o localmente
Com projeto, Web App, serviΓ§os, mΓ³dulos, entidades, migrations, APIs, Commands e Queries prontos, valide a aplicaΓ§Γ£o antes de gerar imagens Docker. Primeiro, compile a soluΓ§Γ£o para confirmar que todos os projetos, contratos e clients gerados continuam coerentes:
dotnet build
Em seguida, execute a aplicaΓ§Γ£o pelo AppHost do Aspire:
dotnet run --project src/Aspire/AppHost/<ProjectName>.AppHost.csproj
Use o dashboard do Aspire para conferir se APIs, Web App, banco de dados, cache, mensageria e Background Jobs subiram corretamente. Depois, teste os fluxos principais no Backoffice: pΓ‘ginas geradas, chamadas do Blazor para os projetos Api.Client, migrations aplicadas, autenticaΓ§Γ£o quando habilitada, e eventos ou jobs quando fizerem parte do cenΓ‘rio.
Quando a aplicaΓ§Γ£o compilar, executar localmente e os fluxos principais estiverem validados, o projeto estarΓ‘ pronto para a etapa de empacotamento.
Gerando imagens Docker
Depois que a aplicaΓ§Γ£o compila, roda localmente pelo AppHost e os fluxos principais foram testados, vocΓͺ pode gerar imagens Docker dos serviΓ§os e aplicaΓ§Γ΅es web para posterior publicaΓ§Γ£o em um registro de contΓͺineres.
Use lino build quando os itens selecionados estiverem prontos para empacotamento como imagens.
O Lino CLI simplifica esse processo com o comando:
lino build
Ao executar, vocΓͺ verΓ‘ uma lista de todos os serviΓ§os e aplicaΓ§Γ΅es web disponΓveis no projeto, juntamente com suas versΓ΅es atuais:
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|
VocΓͺ pode selecionar um ou mais serviΓ§os e aplicaΓ§Γ΅es web para gerar imagens simultaneamente. Basta marcar os itens desejados.
Em seguida, serΓ‘ solicitado escolher como deseja atualizar a versΓ£o das imagens geradas. As opΓ§Γ΅es disponΓveis sΓ£o:
- Manter a versΓ£o atual β nΓ£o altera a versΓ£o existente;
- Patch β incrementa a versΓ£o de patch (ex.: 0.1.0 β 0.1.1);
- Minor β incrementa a versΓ£o menor (ex.: 0.1.0 β 0.2.0);
- Major β incrementa a versΓ£o principal (ex.: 0.1.0 β 1.0.0).
ApΓ³s selecionar os serviΓ§os e definir o incremento de versΓ£o, o Lino CLI realiza:
- Build do cΓ³digo de cada serviΓ§o e aplicaΓ§Γ£o web;
- GeraΓ§Γ£o da imagem Docker correspondente;
- AplicaΓ§Γ£o da tag com a versΓ£o definida;
- DisponibilizaΓ§Γ£o das imagens para publicaΓ§Γ£o em seu registro de contΓͺineres;
- Uso de parΓ’metros de publish como
-c Release,-p:PublishProfile=DefaultContainer,-p:ContainerRepository,-p:ContainerImageTage-p:ContainerLabelVersion, conforme o tipo de projeto gerado.
Ao final do processo, considerando que todos os serviΓ§os e aplicaΓ§Γ΅es web foram selecionados, as imagens geradas terΓ£o a seguinte estrutura:
- my-app/services/catalog-host - tag: 0.1.0
- my-app/services/sales-api - tag: 0.1.0
- my-app/services/security-api - tag: 0.1.0
- my-app/services/stock-api - tag: 0.1.0
- my-app/webapps/backoffice - tag: 0.1.0
Em termos gerais, serviΓ§os simples tendem a gerar repositΓ³rios como project-name/services/service-name-api:1.2.3, serviΓ§os modulares usam hosts como project-name/services/service-name-host:1.2.3, e aplicaΓ§Γ΅es Blazor usam caminhos como project-name/webapps/webapp-name:1.2.3.
ObservaΓ§Γ£o: Esse processo garante consistΓͺncia entre o cΓ³digo e a versΓ£o das imagens Docker, facilitando o deploy e a manutenΓ§Γ£o de mΓΊltiplos ambientes, alΓ©m de permitir que cada serviΓ§o seja isolado em contΓͺineres independentes. Depois que a imagem local for gerada, publique-a no registro usado pela sua plataforma de deploy, como Docker Hub, GitHub Container Registry, AWS ECR, Azure Container Registry ou outro registro compatΓvel com OCI. NΓ£o inclua secrets, connection strings de produΓ§Γ£o ou credenciais dentro da imagem.
Criando versΓ΅es na aplicaΓ§Γ£o
O Lino mantΓ©m a versΓ£o operacional de cada serviΓ§o em src/Services/<ServiceName>/version.txt e de cada aplicaΓ§Γ£o web em src/WebApps/<WebAppName>/version.txt. Isso permite planejar releases independentes para cada item implantΓ‘vel.
Antes de alterar versΓ΅es, inspecione o estado atual:
lino version list
Use lino version show quando precisar consultar um serviΓ§o ou aplicaΓ§Γ£o web especΓfica.
Incrementar novas versΓ΅es aos serviΓ§os ou aplicaΓ§Γ΅es web Γ© um processo simples e centralizado no Lino CLI. Basta executar o comando:
lino version bump
Assim como na geraΓ§Γ£o de imagens Docker, ao executar esse comando vocΓͺ verΓ‘ uma lista completa de todos os serviΓ§os e aplicaΓ§Γ΅es web do seu projeto. Apenas os itens que vocΓͺ selecionar terΓ£o sua versΓ£o incrementada, enquanto os demais permanecerΓ£o inalterados.
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|
ApΓ³s selecionar os itens desejados, vocΓͺ serΓ‘ solicitado a escolher o tipo de incremento de versΓ£o. As opΓ§Γ΅es disponΓveis sΓ£o:
- Patch β pequenas correΓ§Γ΅es sem impacto funcional;
- Minor β adiΓ§Γ£o de novas funcionalidades compatΓveis com versΓ΅es anteriores;
- Major β alteraΓ§Γ΅es que podem quebrar compatibilidade com versΓ΅es anteriores.
Γ importante destacar que as versΓ΅es dos serviΓ§os e aplicaΓ§Γ΅es web tΓͺm impacto direto em:
- As tags das imagens Docker;
- As pastas utilizadas para armazenar scripts gerados pelas migraΓ§Γ΅es de banco de dados;
- O controle de releases e histΓ³rico do projeto;
- Notas de release, manifests de deploy e comunicaΓ§Γ£o com consumidores de API.
Antes de aplicar um bump, revise mudanΓ§as de cΓ³digo, migrations, eventos de integraΓ§Γ£o, contratos de API e alteraΓ§Γ΅es no frontend que fazem parte do release. Uma versΓ£o Patch deve representar correΓ§Γ΅es compatΓveis, Minor deve representar adiΓ§Γ΅es compatΓveis, e Major deve ser reservado para mudanΓ§as que exigem adaptaΓ§Γ£o de consumidores.
Com isso, concluΓmos o guia passo a passo de todos os comandos essenciais para a construΓ§Γ£o de um projeto web utilizando o Lino CLI, desde a instalaΓ§Γ£o, criaΓ§Γ£o de serviΓ§os, entidades, eventos e pΓ‘ginas, atΓ© a geraΓ§Γ£o de imagens Docker e versionamento. O fluxo completo fica rastreΓ‘vel: modelar domΓnio, gerar casos de uso e telas, validar com builds e testes, criar migrations, publicar imagens com tags de versΓ£o e liberar cada serviΓ§o ou aplicaΓ§Γ£o web com um valor SemVer explΓcito.
NΓ£o deixe de acompanhar nosso canal no YouTube para acompanhar tutoriais detalhados, demonstraΓ§Γ΅es prΓ‘ticas e dicas de uso da ferramenta, desde operaΓ§Γ΅es simples atΓ© recursos avanΓ§ados.
