InstalaciΓ³n y configuraciΓ³n de Lino CLI
El primer paso para empezar a trabajar con el Lino CLI es instalar la herramienta en su entorno de desarrollo.
Se distribuye como una dotnet global tool, lo que significa que estarΓ‘ disponible para cualquier proyecto .NET en su computadora.
Antes de instalar, confirme que el SDK de .NET requerido por los templates actuales estΓ© disponible, que la terminal pueda ejecutar dotnet y que el directorio de herramientas globales de .NET estΓ© en el PATH.
Paso 1: instalaciΓ³n
Para instalar (o actualizar) Lino CLI, ejecute el siguiente comando en la terminal:
dotnet tool install --global Tolitech.Lino
Notas importantes:
- Si ya hay una versiΓ³n instalada, puede usar
dotnet tool update --global Tolitech.Lino para actualizar.
- Verifique que el directorio de herramientas globales de .NET estΓ© en el
PATH del sistema para que el comando lino funcione correctamente.
Paso 2: configurar el idioma
DespuΓ©s de la instalaciΓ³n, se recomienda configurar el idioma (o cultura) que CLI utilizarΓ‘ en mensajes, prompts y logs:
lino preferences culture set
Se le pedirΓ‘ que elija entre los idiomas disponibles. Esta configuraciΓ³n garantiza que todas las instrucciones y mensajes aparezcan de forma coherente en el idioma deseado.
Esta preferencia cambia los mensajes, prompts y orientaciones localizadas del CLI; no renombra entidades, servicios, mΓ³dulos o tΓ©rminos de negocio generados en el proyecto.
Paso 3: AutenticaciΓ³n y registro
Para acceder a todos los recursos de Lino, incluidos templates avanzados, la publicaciΓ³n de imΓ‘genes Docker y las integraciones con servicios externos, es necesario estar autenticado.
- Si aΓΊn no posee registro, regΓstrese con el comando:
- Si ya tiene registro, haga login con:
Lo que sucede: el CLI almacena un token de autenticaciΓ³n localmente, lo que le permite ejecutar comandos que requieren acceso a recursos protegidos sin tener que iniciar sesiΓ³n en cada uso.
Mantenga este token privado y evite compartir el mismo perfil de usuario entre diferentes desarrolladores, agentes de CI o mΓ‘quinas.
Paso 4: VerificaciΓ³n
Para confirmar que la instalaciΓ³n y la autenticaciΓ³n fueron exitosas, ejecute:
Si el comando devuelve la versiΓ³n instalada, estΓ‘ listo para comenzar a usar el Lino CLI en sus proyectos.
Crear el proyecto MyApp
En este paso, crearemos la estructura inicial del proyecto utilizando el Lino CLI.
Este proyecto servirΓ‘ como base para demostrar la creaciΓ³n de servicios, mΓ³dulos, front-end y toda la integraciΓ³n de eventos.
Un proyecto Lino no es solo una carpeta con una soluciΓ³n: define convenciones para lΓmites de servicios, bibliotecas compartidas, host Aspire, marco de interfaz, pruebas, administraciΓ³n de paquetes, analizadores y configuraciones que los siguientes Commands reutilizan.
Paso 1: ejecutar el comando crear
Para crear un nuevo proyecto, ejecute el siguiente comando en la terminal:
CLI lo guiarΓ‘ paso a paso, solicitΓ‘ndole informaciΓ³n como:
- Nombre del proyecto: usaremos
MyApp, pero puedes elegir el nombre que quieras;
- CaracterΓsticas adicionales: analizadores de cΓ³digo, almacenamiento en cachΓ© distribuido, soporte de eventos asincrΓ³nicos, etc.
Paso 2: configurar funciones esenciales
Para este proyecto, recomendamos habilitar las siguientes funciones desde el principio:
- Analizadores de cΓ³digo: garantizar que el cΓ³digo siga buenas prΓ‘cticas y estΓ‘ndares consistentes, evitando errores comunes de implementaciΓ³n;
- CachΓ© distribuido: mejora el rendimiento de la aplicaciΓ³n en escenarios con mΓΊltiples servicios, evitando Queries innecesarias a la base de datos;
- ComunicaciΓ³n asincrΓ³nica: Permite el uso de eventos y colas para la integraciΓ³n entre servicios, asegurando escalabilidad y desacoplamiento.
Es importante habilitar todas estas opciones en este proyecto, ya que crearemos mΓΊltiples servicios que se comunicarΓ‘n a travΓ©s de eventos de integraciΓ³n.
Esto le permitirΓ‘ comprender cΓ³mo estructurar sistemas modulares y distribuidos utilizando Lino.
Paso 3: estructura generada
DespuΓ©s de ejecutar el comando y configurar los recursos, CLI generarΓ‘ la estructura inicial del proyecto. IncluirΓ‘:
- Carpetas de servicios y mΓ³dulos;
- Templates para front-end (si corresponde);
- Configuraciones iniciales de cachΓ©, eventos e integraciones;
- Archivos de soluciΓ³n (.slnx) y proyecto (.csproj) listos para su compilaciΓ³n.
Ahora tu proyecto Mi aplicaciΓ³n estΓ‘ listo para recibir los servicios, mΓ³dulos, entidades y front-end que configuraremos en los prΓ³ximos pasos.
Antes de continuar, abra la soluciΓ³n generada y ejecute dotnet build para confirmar que las referencias, los source generators, los templates, los archivos de proyecto y la configuraciΓ³n inicial son coherentes.
Agregar la aplicaciΓ³n web Backoffice
Un sistema completo normalmente necesita al menos una aplicaciΓ³n web para operar el dominio. En esta guΓa, la aplicaciΓ³n se llama Backoffice y representa una interfaz interna para administradores, gerentes o usuarios operativos para monitorear productos, categorΓas, existencias, ventas y otra informaciΓ³n del sistema.
La aplicaciΓ³n web no reemplaza los servicios de dominio. ActΓΊa como un punto de entrada visual para consumir APIs, activar Commands, consultar Queries y exponer pantallas coherentes con las reglas ya modeladas en los servicios.
Paso 1: ejecutar el comando crear
Para agregar una nueva aplicaciΓ³n web al proyecto, use:
El alias lino webapp new tambiΓ©n estΓ‘ disponible para facilitar la escritura. Durante la ejecuciΓ³n, indique un nombre claro para la aplicaciΓ³n web; en este ejemplo, usaremos Backoffice.
lino web-app new --name Backoffice
Paso 2: comprender la estructura generada
Al final del proceso, Lino crea la estructura inicial de la Web App en src/WebApps/<WebAppName>. Para una aplicaciΓ³n Blazor, la estructura puede incluir proyectos server/client, recursos compartidos, archivos de localizaciΓ³n, clients para consumir APIs y convenciones que serΓ‘n utilizadas posteriormente por lino page new.
- Carpetas para pΓ‘ginas, componentes, diseΓ±os, servicios y recursos de aplicaciones;
- Clientes HTTP y contratos requeridos para consumir API expuestos por los servicios del proyecto;
- Resources de localizaciΓ³n y templates iniciales usados por la experiencia web;
- Proyectos cliente/servidor cuando el tipo de aplicaciΓ³n requiera esta separaciΓ³n;
- Convenciones de ruta, navegaciΓ³n e integraciΓ³n que serΓ‘n reutilizadas en la generaciΓ³n de pΓ‘ginas;
- Puntos de integraciΓ³n con autenticaciΓ³n y autorizaciΓ³n cuando se agrega la funcionalidad de auth al proyecto.
Paso 3: CuΓ‘ndo crear la aplicaciΓ³n web en el flujo
Si ya sabe que el sistema tendrΓ‘ una interfaz Blazor, cree la Web App al principio, despuΓ©s de crear el proyecto. AsΓ, los servicios, mΓ³dulos, entidades, APIs y pΓ‘ginas generados despuΓ©s ya quedan alineados con la aplicaciΓ³n web que los consumirΓ‘.
Este flujo es especialmente ΓΊtil porque los servicios creados posteriormente tambiΓ©n generan proyectos tipados de Api.Contracts y Api.Client, consumidos por el proyecto Blazor. Con la Web App presente desde el inicio, resulta mΓ‘s simple validar el camino completo: dominio, API, contratos, HttpClient y pantalla.
Notas importantes
- Backoffice debe consumir los datos por medio de las APIs generadas, manteniendo la lΓ³gica de negocio en los servicios y mΓ³dulos correctos.
- Antes de exponer pΓ‘ginas administrativas, revise la autenticaciΓ³n, autorizaciΓ³n, roles, permisos y polΓticas de acceso.
- Puede crear mΓΊltiples aplicaciones web, por ejemplo un
Backoffice interno y un Site pΓΊblico, cuando los pΓΊblicos, permisos, deploys o responsabilidades sean diferentes.
- Evite mezclar flujos pΓΊblicos y administrativos en la misma aplicaciΓ³n web cuando esto dificulte la seguridad, la navegaciΓ³n, la implementaciΓ³n o la propiedad del equipo.
Con la aplicaciΓ³n web creada, la guΓa puede pasar a los servicios y mΓ³dulos que proporcionarΓ‘n los datos y reglas de negocio que consume esta interfaz.
CreaciΓ³n de servicios y mΓ³dulos.
En este paso, construiremos los servicios y mΓ³dulos que conformarΓ‘n la aplicaciΓ³n.
El objetivo es crear una arquitectura modular y escalable, permitiendo que diferentes Γ‘reas del sistema, como productos, categorΓas, inventario, ventas y medios, evolucionen de forma independiente, manteniendo la cohesiΓ³n y facilitando el mantenimiento.
Los servicios definen los lΓmites de deploy y persistencia; los mΓ³dulos organizan Γ‘reas de negocio dentro de un servicio modular. Antes de crear archivos, evalΓΊe quΓ© partes del dominio necesitan base de datos propia, release independiente, contrato de integraciΓ³n u ownership separado.
Paso 1: Definir los servicios
Inicialmente, crearemos los siguientes servicios, cada uno con responsabilidades bien definidas:
- Catalog (modular) β responsable de gestionar productos, categorΓas y precios;
- Sales β responsable de procesar ventas y pedidos;
- Stock β responsable de la gestiΓ³n de stocks y movimientos;
- Security β responsable de la autenticaciΓ³n, autorizaciΓ³n y gestiΓ³n de usuarios.
Para crear los servicios del ejemplo, ejecute un comando por cada servicio. En el wizard de Catalog, elija arquitectura modular; en los demΓ‘s, elija la arquitectura adecuada para una frontera simple.
lino service new --name Catalog
lino service new --name Sales
lino service new --name Stock
lino service new --name Security
Durante la ejecuciΓ³n del comando, el CLI solicitarΓ‘:
- Nombre del servicio: por ejemplo,
Catalog;
- Nombre para mostrar y estilo arquitectΓ³nico: elija una arquitectura simple para fronteras compactas o modular cuando el servicio tenga Γ‘reas cohesivas independientes;
- Base de datos: elija la tecnologΓa que mejor se adapte a su proyecto (SQL Server, PostgreSQL, etc.);
Paso 2: Creando mΓ³dulos dentro de servicios
No todos los servicios necesitan ser modulares. En nuestro proyecto, solo el servicio Catalog tendrΓ‘ mΓ³dulos, para separar responsabilidades como merchandising y precios.
Definimos los siguientes mΓ³dulos para el servicio Catalog:
- Merchandising β gestiΓ³n de productos y categorΓas;
- Pricing β gestiΓ³n de precios, promociones e historial de cambios.
Para crear los mΓ³dulos de Catalog, ejecute:
lino module new --service Catalog --name Merchandising
lino module new --service Catalog --name Pricing
Puedes crear tantos mΓ³dulos como quieras dentro del servicio modular Catalog.
AdemΓ‘s, dependiendo de la complejidad, algunos mΓ³dulos podrΓan convertirse en servicios independientes en el futuro.
La separaciΓ³n que aquΓ se presenta es sΓ³lo para fines didΓ‘cticos y sirve como ejemplo de organizaciΓ³n modular.
No use mΓ³dulos solo para crear carpetas; ΓΊselos cuando protejan un Γ‘rea de negocio con entidades propias, casos de uso, APIs, migrations y eventos.
Estructura final del proyecto
DespuΓ©s de crear los servicios y mΓ³dulos, su soluciΓ³n deberΓa tener una estructura similar a la siguiente:
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/
ExplicaciΓ³n de la estructura:
Services/: contiene todos los servicios del sistema, cada uno aislado con su propia lΓ³gica empresarial, infraestructura y alojamiento;
Modules/: carpetas dentro de servicios modulares, que le permiten organizar funcionalidades especΓficas y mantener un cΓ³digo coherente;
WebApps/: frontends asociados al sistema, ya integrados con los servicios;
Shared/: bibliotecas y recursos compartidos entre servicios y frontends;
tests/: pruebas unitarias y de integraciΓ³n organizadas por servicio y mΓ³dulo.
Con esta estructura modular, cada equipo o desarrollador puede trabajar de forma independiente en diferentes partes del sistema, facilitando la escalabilidad, el mantenimiento y las pruebas.
DespuΓ©s de crear servicios y mΓ³dulos, ejecute dotnet build para confirmar que los proyectos estΓ‘n conectados correctamente a la soluciΓ³n, el host Aspire, los proyectos compartidos y la estructura de pruebas.
Agregar autenticaciΓ³n y autorizaciΓ³n
La autenticaciΓ³n y la autorizaciΓ³n son elementos esenciales de cualquier sistema moderno.
La autenticaciΓ³n comprueba quiΓ©n es el usuario; la autorizaciΓ³n define quΓ© puede ejecutar ese usuario. En Lino CLI, la funcionalidad de auth genera la base necesaria para usuarios, roles, permisos, tokens, polΓticas de acceso e integraciΓ³n con APIs.
Paso 1: ejecutar el comando de autenticaciΓ³n
Para agregar recursos de autenticaciΓ³n y autorizaciΓ³n, use el comando:
CLI lo guiarΓ‘ a travΓ©s de los siguientes pasos:
-
ElecciΓ³n de servicio o mΓ³dulo: debe indicar dΓ³nde se instalarΓ‘n los artefactos de autenticaciΓ³n.
En nuestro proyecto de ejemplo, utilizamos el servicio Security, que centraliza toda la lΓ³gica de seguridad del sistema;
- Configuraciones adicionales: creaciΓ³n de tablas de usuarios, roles, permisos, tokens y configuraciΓ³n de polΓticas de acceso;
- Vida ΓΊtil del token: definiciΓ³n de vencimiento para el access token y el refresh token de acuerdo con la polΓtica de seguridad del producto;
- Tipo de identificador de usuario: elegir el tipo utilizado por el modelo de usuario y los contratos generados.
Paso 2: estructura generada
DespuΓ©s de ejecutar el comando, el servicio Security contendrΓ‘ archivos y carpetas como:
- Domain/Entities: agregados, entidades y reglas para usuarios, roles, permisos y tokens;
- Infrastructure/Persistence: configuraciones de base de datos, mapeos de Entity Framework y migrations para tablas de seguridad;
- Application: Commands, Queries, Handlers, servicios de autenticaciΓ³n, generaciΓ³n de tokens, validaciΓ³n de credenciales y comprobaciones de permisos;
- API/Host: endpoints para login, logout, registro, refresh token y operaciones protegidas;
- IntegraciΓ³n con la aplicaciΓ³n web: soporte para flujos autenticados cuando una aplicaciΓ³n web estΓ‘ presente.
Con esto, su aplicaciΓ³n tendrΓ‘ una autenticaciΓ³n sΓ³lida y un control de acceso granular, lista para admitir mΓΊltiples usuarios y diferentes niveles de permisos.
Aun asΓ, el cΓ³digo generado debe tratarse como una base sΓ³lida, no como la revisiΓ³n de seguridad final. Antes de producciΓ³n, revise la vida ΓΊtil de los tokens, el diseΓ±o de permisos, la polΓtica de contraseΓ±as, HTTPS, secrets, rate limiting, logs y las configuraciones de deploy.
Agregar Background Jobs
En sistemas distribuidos y modulares, como el que estamos construyendo con Lino CLI, no todos los servicios se comunican directamente entre sΓ.
Para garantizar la coherencia y confiabilidad en el intercambio de informaciΓ³n, utilizamos eventos de integraciΓ³n.
Sin embargo, para procesar estos eventos de manera eficiente y asincrΓ³nica, necesitamos Background Jobs.
Lino utiliza el estΓ‘ndar Outbox Pattern para garantizar que todos los mensajes generados por los servicios se registren de manera confiable antes de ser enviados.
Con esto logramos:
- Evitar pΓ©rdida de eventos en caso de fallas o reinicios del servicio;
- Garantizar que el mismo mensaje se envΓe solo una vez;
- Permitir el reprocesamiento de mensajes en caso de falla en la entrega;
- Separar el procesamiento de eventos de la lΓ³gica principal de la aplicaciΓ³n, mejorando el rendimiento y la escalabilidad.
Paso 1: ejecutar el comando
Para agregar soporte para Background Jobs a su proyecto, ejecute el comando:
lino feature background-job add
CLI le pedirΓ‘ que seleccione el servicio donde se instalarΓ‘ el Background Job. Generalmente elegirΓ‘s el servicio que centralice la producciΓ³n del evento, como por ejemplo Catalog o Sales.
En las opciones actuales, el asistente tambiΓ©n puede solicitar el mΓ³dulo, la biblioteca de jobs, si se deben procesar los eventos de Outbox, la programaciΓ³n y el tamaΓ±o del lote. El flujo de los templates actuales usa Hangfire para la ejecuciΓ³n recurrente de los jobs.
Paso 2: Configurar la ejecuciΓ³n
Durante la configuraciΓ³n, podrΓ‘ definir:
- Intervalo de control: determina la frecuencia con la que el Background Job comprobarΓ‘ la tabla Outbox para mensajes nuevos. Un intervalo demasiado corto puede aumentar el uso de recursos, mientras que un intervalo demasiado largo puede retrasar la entrega de eventos;
- Lote de registros procesados ββa la vez: controla cuΓ‘ntos eventos se leerΓ‘n y enviarΓ‘n por ejecuciΓ³n. Los lotes mΓ‘s grandes pueden aumentar el rendimiento, pero requieren mΓ‘s memoria y procesamiento;
- PolΓtica de retries: en caso de error al enviar mensajes, puede configurar cuΓ‘ntas veces el job intentarΓ‘ reenviarlos.
Estos parΓ‘metros dependen del tamaΓ±o de su sistema, la capacidad de la mΓ‘quina y el volumen esperado de eventos.
Paso 3: estructura generada
DespuΓ©s de la configuraciΓ³n, el proyecto tendrΓ‘ un Background Job listo para procesar mensajes de las tablas Outbox en cada servicio.
- El caso de uso cambia el dominio y registra un dominio o evento de integraciΓ³n.
- La unidad de trabajo guarda los datos de negocio y los mensajes de Outbox en la misma transacciΓ³n.
- Hangfire ejecuta jobs recurrentes que leen mensajes pendientes en lotes.
- Los mensajes se publican en el motor de integraciΓ³n configurado, como RabbitMQ, cuando la comunicaciΓ³n asincrΓ³nica estΓ‘ habilitada.
- Los mensajes completados, fallidos, antiguos o atascados pueden manejarse mediante la lΓ³gica y la configuraciΓ³n generadas para el job.
Esto garantiza que todos los eventos de integraciΓ³n se procesen de manera confiable y eficiente, lo que permite que mΓΊltiples servicios y mΓ³dulos se comuniquen de forma asincrΓ³nica, sin afectar el rendimiento del sistema principal.
La regla operativa mΓ‘s importante es mantener claros los lΓmites transaccionales: los eventos que deben enviarse a travΓ©s de Outbox deben crearse en el mismo flujo transaccional que el cambio de negocio que representan.
Crear entidades y enumeraciones
En esta secciΓ³n, detallaremos el diseΓ±o de las entidades, enumeraciones y Value Objects de la aplicaciΓ³n, mostrando en quΓ© servicios y mΓ³dulos se crearΓ‘ cada elemento.
1. Crear la entidad Category
Para crear la entidad Category en el servicio Catalog y en el mΓ³dulo Merchandising, ejecute:
lino entity new --service Catalog --module Merchandising --name Category
La entidad se crearΓ‘ en el servicio Catalog y en el modulo Merchandising con la siguiente estructura:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β PK β FK β Property name β Type β Length β Required β Auto-increment β
ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β x β β Id β Guid β β x β x β
ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌβββββββββββΌβββββββββββββββββ€
β β β Name β string β 50 β x β β
ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
2. Crear la entidad Product
A continuaciΓ³n, creamos la entidad Product en el mismo servicio y mΓ³dulo. En este flujo, el Value Object ProductDimension y la enum ProductStatus se configuran dentro del propio wizard de creaciΓ³n de la entidad, como parte del agregado Product:
lino entity new --service Catalog --module Merchandising --name Product
Durante la ejecuciΓ³n, agregue las propiedades simples, la relaciΓ³n con Category, la propiedad Dimensions de tipo Value Object y la propiedad Status de 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 el Value Object ProductDimension dentro de Product
En el escenario de esta guΓa, ProductDimension no se crea mediante un comando separado. Se agrega durante el lino entity new de Product, como la propiedad Dimensions, y representa las dimensiones del producto:
βββββββββββββββββ¬ββββββββββ¬βββββββββ¬βββββββββββ
β Property name β Type β Length β Required β
βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€
β Width β decimal β β x β
βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€
β Height β decimal β β x β
βββββββββββββββββΌββββββββββΌβββββββββΌβββββββββββ€
β Depth β decimal β β x β
βββββββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββ
Nota: el comando lino value-object new existe para escenarios en los que el Value Object debe crearse por separado. En esos casos, use los argumentos del servicio y del mΓ³dulo de destino:
lino value-object new --service <ServiceName> --module <ModuleName> --name <ValueObjectName>
2.2 Configurando la Enum ProductStatus dentro de Product
Del mismo modo, ProductStatus se configura dentro del lino entity new de Product, como la propiedad Status. Define el estado del producto:
βββββββββ¬βββββββββββββββ¬βββββββββββββββ
β Value β Name β Display Name β
βββββββββΌβββββββββββββββΌβββββββββββββββ€
β 1 β Active β Active β
βββββββββΌβββββββββββββββΌβββββββββββββββ€
β 2 β Inactive β Inactive β
βββββββββΌβββββββββββββββΌβββββββββββββββ€
β 3 β Discontinued β Discontinued β
βββββββββ΄βββββββββββββββ΄βββββββββββββββ
Nota: el comando lino enumeration new tambiΓ©n puede usarse cuando una enum debe crearse por separado en otro escenario:
lino enumeration new --service <ServiceName> --module <ModuleName> --name <EnumerationName>
3. Agregar nuevas propiedades
A medida que el proyecto evoluciona, podemos editar entidades existentes para agregar nuevas propiedades.
Por ejemplo, agregaremos una lista de imΓ‘genes a la entidad Product:
lino entity edit --service Catalog --module Merchandising --entity Product
Dentro de este mismo flujo, creamos la propiedad Images de tipo List<ProductImage>. Como ProductImage pertenece al agregado Product, su estructura tambiΓ©n se configura durante el 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 β β β β
ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββββββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
3.1 Configurando ProductImage dentro de Product
ProductImage no se crea mediante un comando separado en este escenario. Se configura como elemento de la colecciΓ³n Images durante la ediciΓ³n de Product y tiene la siguiente estructura:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββββββββββ¬βββββββββ¬βββββββββββ¬βββββββββββββββββ
β 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: el comando lino entity new existe para crear entidades independientes en otros escenarios. Cuando la entidad no forma parte de la ediciΓ³n de un agregado existente, use:
lino entity new --service <ServiceName> --module <ModuleName> --name <EntityName>
4. CreaciΓ³n de entidades para otros servicios
en servicio Sales, creamos la entidad ProductSnapshot, que se verΓ‘ alimentado por eventos de integraciΓ³n.
Como el ID original de la entidad Product viene del servicio Catalog, aquΓ no puede ser autoincremental.
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 β β
ββββββ΄βββββ΄ββββββββββββββββ΄ββββββββββ΄βββββββββ΄βββββββββββ΄βββββββββββββββββ
ObservaciΓ³n: solo los campos esenciales se replicaron en ProductSnapshot para el servicio Sales. Las entidades complementarias, como Customer, Order y StockItem, no se detallarΓ‘n aquΓ para simplificar la documentaciΓ³n. ProductSnapshot funciona como una shadow entity: una copia local, mΓnima y controlada de datos cuyo dueΓ±o estΓ‘ en otro servicio. Esto permite que Sales consulte los datos necesarios del producto sin depender directamente de la entidad o la base de datos de Catalog.
Este tipo de estructura tambiΓ©n podrΓa crearse con el comando lino shadow new, alias de lino shadow-entity new. En este flujo, Lino copia la estructura de una entidad de otro servicio o mΓ³dulo y permite seleccionar solo las propiedades que tienen sentido para el contexto consumidor.
lino shadow new --service <ServiceName> --module <ModuleName> --name <ShadowEntityName>
En el ejemplo, la entidad de origen es Catalog.Merchandising.Product y el destino es el servicio Sales, manteniendo solo los campos necesarios para ventas.
Crear eventos y sus controladores.
En resumen, en el tema anterior creamos un servicio modular. Catalog.Merchandising las entidades Product, Category y ProductImage, mientras estΓ‘ de servicio Sales creamos la entidad ProductSnapshot.
Ahora, creemos eventos de dominio y eventos de integraciΓ³n. El objetivo es que, al crear o actualizar productos en el servicio Catalog, estos cambios se repliquen en los servicios consumidores, como Sales y Stock.
1. Crear eventos de dominio
El primer paso es crear eventos de dominio. ProductCreated y ProductUpdated con el comando:
Durante la creaciΓ³n podemos asociar el evento a un handler y, simultΓ‘neamente, configurar la activaciΓ³n de un evento de integraciΓ³n. Esto centraliza la creaciΓ³n de todo el flujo necesario.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β 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 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
De la misma forma creamos el 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 esto tenemos:
- Eventos de dominio creados (
ProductCreated y ProductUpdated);
- Controladores de eventos de dominio correspondientes;
- Eventos de integraciΓ³n registrados en Outbox automΓ‘ticamente por el controlador de eventos del dominio.
2. Crear controladores de eventos de integraciΓ³n
El siguiente paso es definir quΓ© servicios consumirΓ‘n los eventos de integraciΓ³n. Para hacer esto, usamos:
El flujo de creaciΓ³n implica:
- Seleccione el servicio, mΓ³dulo y entidad que contendrΓ‘ el controlador;
- Seleccione el evento de integraciΓ³n que se consumirΓ‘ y de quΓ© servicio/mΓ³dulo/entidad provendrΓ‘.
Por ejemplo, en el servicio Sales Creamos los controladores para ProductCreated y ProductUpdated que consumirΓ‘ los eventos desencadenados por el Catalog.Merchandising.Producto:
ββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββ
β 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 esto, tenemos dos controladores de eventos de integraciΓ³n en el servicio Sales, consumiendo sΓ³lo los campos necesarios de los eventos de integraciΓ³n del Catalog.Merchandising.
Esto garantiza que las tablas replicadas conserven solo los datos esenciales, optimizando el almacenamiento y el rendimiento.
En tΓ©rminos de arquitectura, el flujo esperado es: el controlador de Commands cambia el agregado, se genera el evento de dominio, el controlador prepara el evento de integraciΓ³n, Outbox almacena el mensaje, el Background Job procesa el problema y el motor de mensajerΓa entrega el mensaje a los consumidores.
Esto evita el acoplamiento sincrΓ³nico entre servicios y reduce el riesgo de que se cambie la base de datos sin que se publique el evento correspondiente.
Generar pΓ‘ginas web, APIs, Commands y Queries
Una de las grandes ventajas de Lino CLI es permitir la creaciΓ³n integrada de pΓ‘ginas web, APIs, Commands y Queries de forma automatizada, simplificando todo el flujo de desarrollo.
Cuando el modelo de dominio es lo suficientemente estable, este comando crea una ruta completa desde la pantalla hasta la persistencia, haciendo que el trabajo de modelado realizado en los pasos anteriores sea visible para el usuario final.
Para comenzar, simplemente ejecute el comando:
Durante el proceso, usted:
- Seleccionar el servicio, mΓ³dulo y entidad que desea exponer;
- Elegir el tipo y el nombre de la pΓ‘gina que se generarΓ‘;
- Elegir los campos que formarΓ‘n parte del listado;
- Generar automΓ‘ticamente pΓ‘ginas de listado (cuadrΓcula paginada) y formulario de creaciΓ³n/ediciΓ³n;
- Generar clases HttpClient para consumo por parte del frontend;
- Crear contratos de request/response y todas las APIs REST necesarias (POST, PUT, PATCH, DELETE y GET);
- Crear Commands, Queries, Handlers y validators, que llegan hasta la base de datos garantizando el flujo CRUD completo.
Con este comando, obtiene una aplicaciΓ³n funcional sin tener que escribir manualmente la capa de interfaz, APIs y lΓ³gica de negocio, manteniendo el estΓ‘ndar y la coherencia entre los servicios.
Aun asΓ, revise las reglas de negocio y las validaciones despuΓ©s de la generaciΓ³n, porque no todas las reglas se pueden inferir ΓΊnicamente a partir de los metadatos de las propiedades.
Para este proyecto, podemos generar pΓ‘ginas integradas para las siguientes entidades:
- Catalog.Merchandising.
Category
- Catalog.Merchandising.
Product
- Sales.
ProductSnapshot
DespuΓ©s de generar las pΓ‘ginas, APIs y Commands/Queries, la aplicaciΓ³n estarΓ‘ lista para interactuar de forma completa entre frontend y backend, con validaciones, rutas y persistencia ya configuradas automΓ‘ticamente por Lino CLI.
Ejecute dotnet build despuΓ©s de la generaciΓ³n para identificar tempranamente referencias rotas, contratos inconsistentes o impactos de cambios recientes en el modelo.
Crear y aplicar migrations
DespuΓ©s de crear o cambiar entidades, Value Objects, enumeraciones, relaciones, autenticaciΓ³n, soporte a Tenant o persistencia de Background Jobs, genere migrations para mantener la base de datos y el cΓ³digo alineados. La migration transforma el cambio de modelo en un artefacto explΓcito, versionable y revisable.
Lino CLI coordina este proceso con Entity Framework, seleccionando el servicio/mΓ³dulo correcto, utilizando la versiΓ³n actual del servicio y organizando los scripts generados para facilitar la trazabilidad.
Paso 1: crear una migration
Para crear una nueva migration, ejecute:
lino database migrations add
El comando tambiΓ©n puede aceptar alias como lino database migrations new y lino database migrations create, pero la forma preferida en la documentaciΓ³n es add.
Durante la ejecuciΓ³n deberΓ‘ informar:
- El servicio que recibirΓ‘ la migration, por ejemplo.
Catalog;
- El mΓ³dulo afectado, cuando el servicio es modular, p.e.
Merchandising;
- La versiΓ³n actual del servicio, leΓda desde
src/Services/<ServiceName>/version.txt;
- Una descripciΓ³n objetiva de la migration, como por ejemplo
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 β
βββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββ
Cuando ya conozcas el servicio y el mΓ³dulo, puedes introducir estos datos directamente:
lino database migrations add --service <ServiceName> --module <ModuleName>
Paso 2: QuΓ© se genera
Al confirmar la creaciΓ³n, Lino prepara los comandos correctos de Entity Framework para el proyecto de persistencia del servicio o mΓ³dulo seleccionado. En un servicio modular, la migration queda aislada en el mΓ³dulo correspondiente, evitando mezclar cambios de contextos diferentes.
- Una nueva migration de base de datos asociada a la versiΓ³n actual del servicio;
- El script SQL correspondiente, organizado en la capa de persistencia, en una ruta versionada como /scripts//;
- Artefactos compatibles con la estructura de Infrastructure/Persistence del servicio o mΓ³dulo seleccionado;
- Historial rastreable para relacionar la versiΓ³n del servicio, los cambios de esquema y el release de la aplicaciΓ³n.
Paso 3: Listar y aplicar migrations
Antes de aplicar cambios a una base de datos, enumere las migrations conocidas y confirme que la migration esperada estΓ© presente:
lino database migrations list --service <ServiceName> --module <ModuleName>
Para aplicar migrations al entorno configurado:
lino database migrations apply --service <ServiceName> --module <ModuleName>
En desarrollo local, este flujo acelera la validaciΓ³n del modelo. En entornos compartidos o de producciΓ³n, aplique migrations mediante el proceso de deploy definido por el equipo, con revisiΓ³n del script, aprobaciΓ³n y backup cuando sea necesario.
Paso 4: invertir o retirar en un entorno controlado
Use revert cuando necesite revertir una migration aplicada en un entorno controlado, entendiendo que la operaciΓ³n puede ejecutar comandos destructivos segΓΊn el contenido de la migration:
lino database migrations revert --service <ServiceName> --module <ModuleName>
Use remove para descartar la ΓΊltima migration aΓΊn no consolidada, normalmente antes de commitear o publicar el cambio:
lino database migrations remove --service <ServiceName> --module <ModuleName>
Buenas practicas
- Cree migrations siempre que haya cambios en el modelo persistente: nuevas entidades, propiedades, relaciones, Γndices, restricciones, tablas de autenticaciΓ³n o tablas Outbox.
- Revise el cΓ³digo generado y SQL antes de aplicar a entornos compartidos.
- Preste especial atenciΓ³n a los cambios de nombre, cambios de tipo, caΓda de columnas, cambios de clave, cambios de esquema y operaciones que pueden provocar la pΓ©rdida de datos.
- Mantenga la versiΓ³n del servicio alineada con los scripts generados para facilitar la auditorΓa, la rollback planificado y la comunicaciΓ³n de release.
- DespuΓ©s de crear la migration, ejecute build y pruebas relevantes para confirmar que domain, persistence, APIs y pΓ‘ginas generadas siguen siendo coherentes.
Al seguir este flujo, la base de datos permanece coherente con el modelo de dominio definido en Lino, y cada cambio de schema queda documentado, rastreable y listo para ser revisado antes del deploy.
Paso 5: Validando la aplicaciΓ³n localmente
Con el proyecto, Web App, servicios, mΓ³dulos, entidades, migrations, APIs, Commands y Queries listos, valide la aplicaciΓ³n antes de generar imΓ‘genes Docker. Primero, compile la soluciΓ³n para confirmar que todos los proyectos, contratos y clients generados siguen siendo coherentes:
A continuaciΓ³n, ejecute la aplicaciΓ³n mediante el AppHost de Aspire:
dotnet run --project src/Aspire/AppHost/<ProjectName>.AppHost.csproj
Use el dashboard de Aspire para comprobar si APIs, Web App, base de datos, cachΓ©, mensajerΓa y Background Jobs se iniciaron correctamente. DespuΓ©s, pruebe los flujos principales en el Backoffice: pΓ‘ginas generadas, llamadas de Blazor a los proyectos Api.Client, migrations aplicadas, autenticaciΓ³n cuando estΓ© habilitada, y eventos o jobs cuando formen parte del escenario.
Cuando la aplicaciΓ³n compile, se ejecute localmente y los flujos principales estΓ©n validados, el proyecto estarΓ‘ listo para la etapa de empaquetado.
Generar imΓ‘genes Docker
DespuΓ©s de que la aplicaciΓ³n compile, se ejecute localmente mediante el AppHost y los flujos principales hayan sido probados, puede generar imΓ‘genes Docker de los servicios y aplicaciones web para publicarlas posteriormente en un registro de contenedores.
Use lino build cuando los elementos seleccionados estΓ©n listos para empaquetarse como imΓ‘genes.
Lino CLI simplifica este proceso con el comando:
Cuando lo ejecute, verΓ‘ una lista de todos los servicios y aplicaciones web disponibles en el proyecto, junto con sus versiones actuales:
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|
Puede seleccionar uno o mΓ‘s servicios y aplicaciones web para generar imΓ‘genes simultΓ‘neamente. Simplemente marque los elementos deseados.
A continuaciΓ³n, se le pedirΓ‘ que elija cΓ³mo desea actualizar la versiΓ³n de las imΓ‘genes generadas. Las opciones disponibles son:
- Mantener la versiΓ³n actual β no cambia la versiΓ³n existente;
- Patch β incrementa la versiΓ³n del parche (por ejemplo: 0.1.0 β 0.1.1);
- Minor β incrementa la versiΓ³n menor (por ejemplo: 0.1.0 β 0.2.0);
- Major β incrementa la versiΓ³n principal (por ejemplo: 0.1.0 β 1.0.0).
DespuΓ©s de seleccionar los servicios y definir el incremento de versiΓ³n, el Lino CLI realiza:
- Build del cΓ³digo de cada servicio y aplicaciΓ³n web;
- GeneraciΓ³n de la imagen Docker correspondiente;
- AplicaciΓ³n de la tag con la versiΓ³n definida;
- DisponibilizaciΓ³n de las imΓ‘genes para su publicaciΓ³n en su registro de contenedores;
- Uso de parΓ‘metros de publicaciΓ³n como
-c Release, -p:PublishProfile=DefaultContainer, -p:ContainerRepository, -p:ContainerImageTag y -p:ContainerLabelVersion, segΓΊn el tipo de proyecto generado.
Al final del proceso, considerando que se han seleccionado todos los servicios y aplicaciones web, las imΓ‘genes generadas tendrΓ‘n la siguiente estructura:
- 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
En tΓ©rminos generales, los servicios simples tienden a generar repositorios como project-name/services/service-name-api:1.2.3, los servicios modulares utilizan hosts como project-name/services/service-name-host:1.2.3, y las aplicaciones Blazor usan rutas como project-name/webapps/webapp-name:1.2.3.
ObservaciΓ³n: Este proceso garantiza la coherencia entre el cΓ³digo y la versiΓ³n de las imΓ‘genes Docker, facilitando el despliegue y mantenimiento de mΓΊltiples entornos, ademΓ‘s de permitir aislar cada servicio en contenedores independientes.
Una vez generada la imagen local, publΓquela en el registro usado por su plataforma de deploy, como Docker Hub, GitHub Container Registry, AWS ECR, Azure Container Registry u otro registro compatible con OCI. No incluya secrets, connection strings de producciΓ³n ni credenciales dentro de la imagen.
Crear versiones en la aplicaciΓ³n
Lino mantiene la versiΓ³n operativa de cada servicio en src/Services/<ServiceName>/version.txt y cada aplicaciΓ³n web en src/WebApps/<WebAppName>/version.txt. Esto le permite planificar releases independientes para cada elemento implementable.
Antes de cambiar de versiΓ³n, inspeccione el estado actual:
Use lino version show cuando necesite consultar un servicio o una aplicaciΓ³n web especΓfica.
Incrementar versiones de servicios o aplicaciones web es un proceso simple y centralizado en Lino CLI. Simplemente ejecute el comando:
Al igual que generar imΓ‘genes Docker, cuando ejecute este comando verΓ‘ una lista completa de todos los servicios y aplicaciones web en su proyecto.
Solo los elementos que seleccione tendrΓ‘n su versiΓ³n incrementada, mientras que los demΓ‘s permanecerΓ‘n sin cambios.
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|
DespuΓ©s de seleccionar los elementos deseados, se le pedirΓ‘ que elija el tipo de incremento de versiΓ³n. Las opciones disponibles son:
- Patch β pequeΓ±as correcciones sin impacto funcional;
- Minor β adiciΓ³n de nuevas funciones compatibles con versiones anteriores;
- Major β cambios que pueden romper la compatibilidad con versiones anteriores.
Es importante resaltar que las versiones de los servicios y aplicaciones web tienen un impacto directo en:
- Las tags de las imΓ‘genes Docker;
- Las carpetas utilizadas para almacenar scripts generados por migrations de base de datos;
- Control de releases e historial de proyectos;
- Notas de release, manifests de deploy y comunicaciΓ³n con los consumidores de API.
Antes de aplicar un bump, revise los cambios de cΓ³digo, las migrations, los eventos de integraciΓ³n, los contratos de API y los cambios en el frontend que forman parte del release. Una versiΓ³n Patch debe representar correcciones compatibles, Minor debe representar adiciones compatibles, y Major debe reservarse para cambios que requieran adaptaciΓ³n de los consumidores.
Con esto, concluimos la guΓa paso a paso de todos los comandos esenciales para construir un proyecto web usando Lino CLI, desde la instalaciΓ³n, la creaciΓ³n de servicios, entidades, eventos y pΓ‘ginas, hasta la generaciΓ³n y el versionado de imΓ‘genes Docker.
El flujo completo es rastreable: modelado de dominio, generaciΓ³n de casos de uso y pantallas, validaciΓ³n con compilaciones y pruebas, creaciΓ³n de migrations, publicaciΓ³n de imΓ‘genes con tags de versiΓ³n y release de cada servicio o aplicaciΓ³n web con un valor SemVer explΓcito.
No olvides seguir nuestro canal en YouTube para seguir tutoriales detallados, demostraciones prΓ‘cticas y consejos para usar la herramienta, desde operaciones simples hasta recursos avanzados.