De cero a la build: guía paso a paso

Este tema presenta una guΓ­a prΓ‘ctica y paso a paso para usar Lino CLI como herramienta principal en la construcciΓ³n de un proyecto: desde la instalaciΓ³n y configuraciΓ³n inicial, pasando por la generaciΓ³n de servicios, mΓ³dulos y entidades, hasta funciones avanzadas como eventos, trabajos en segundo plano, migraciones, construcciΓ³n de imΓ‘genes Docker y control de versiones.


El objetivo es mostrar de manera integrada cΓ³mo los comandos del CLI encajan en el flujo de desarrollo real β€” no solo listarlos, sino explicar el porquΓ© de cada elecciΓ³n, quΓ© se genera automΓ‘ticamente y cuΓ‘les son las implicaciones arquitectΓ³nicas.


Aunque cada comando ya tenga documentaciΓ³n especΓ­fica, aquΓ­ verΓ‘s el proceso de principio a fin β€” un recorrido reproducible que ahorra horas de trabajo repetitivo y ayuda a mantener un cΓ³digo consistente y testeable.


A lo largo de la guΓ­a explicaremos conceptos tΓ©cnicos aplicados por Lino (por ejemplo: CQRS, TypedResults, Source Generators, Outbox Pattern), mostraremos ejemplos de comandos e indicaremos buenas prΓ‘cticas para versionado, despliegue e integraciΓ³n continua.

InstalaciΓ³n y configuraciΓ³n de Lino CLI

El primer paso para comenzar a trabajar con Lino CLI es instalar la herramienta en su entorno de desarrollo. Se distribuye como una herramienta global de dotnet, lo que significa que estarΓ‘ disponible para cualquier proyecto .NET en su computadora.

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 actualizarla.
  • AsegΓΊrese de que el directorio de herramientas globales de .NET estΓ© en el PATH del sistema para que el comando lino funcione correctamente.

Paso 2: Configurar idioma

DespuΓ©s de la instalaciΓ³n, se recomienda configurar el idioma (o cultura) que el CLI utilizarΓ‘ en mensajes, avisos y registros:

lino preferences culture set

Se le pedirΓ‘ que elija entre los idiomas disponibles. Esta configuraciΓ³n garantiza que todas las instrucciones y avisos aparezcan de manera consistente en el idioma deseado.

Paso 3: AutenticaciΓ³n y registro

Para acceder a todas las funciones de Lino, incluidos templates avanzados, publicaciΓ³n de imΓ‘genes Docker e integraciΓ³n con servicios externos, es necesario autenticarse.

- Si aΓΊn no tiene una cuenta, regΓ­strese con el comando:

lino user register

- Si ya tiene una cuenta, inicie sesiΓ³n con:

lino auth login

QuΓ© 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 cada vez.

Paso 4: VerificaciΓ³n

Para confirmar que la instalaciΓ³n y autenticaciΓ³n se realizaron correctamente, ejecute:

lino --version

Si el comando devuelve la versiΓ³n instalada, estΓ‘ listo para comenzar a usar Lino CLI en sus proyectos.

Creando el proyecto MyApp

En este paso, vamos a crear la estructura inicial del proyecto utilizando Lino CLI. Este proyecto servirΓ‘ como base para demostrar la creaciΓ³n de servicios, mΓ³dulos, front-end y la integraciΓ³n de eventos.

Paso 1: Ejecutar el comando de creaciΓ³n

Para crear un nuevo proyecto, ejecute el siguiente comando en la terminal:

lino project new

El CLI lo guiarΓ‘ paso a paso, solicitando informaciΓ³n como:

  • Nombre del proyecto: usaremos MyApp, pero puede elegir cualquier nombre que desee;
  • Funciones adicionales: analizadores de cΓ³digo, cachΓ© distribuido, soporte para eventos asincrΓ³nicos, etc.

Paso 2: ConfiguraciΓ³n de funciones esenciales

Para este proyecto, recomendamos habilitar desde el inicio las siguientes funciones:

  • Analizadores de cΓ³digo: para asegurar 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 consultas innecesarias a la base de datos;
  • ComunicaciΓ³n asincrΓ³nica: habilita el uso de eventos y colas para la integraciΓ³n entre servicios, garantizando escalabilidad y desacoplamiento.

Es importante habilitar todas estas opciones en este proyecto, ya que crearemos mΓΊltiples servicios que se comunicarΓ‘n mediante eventos de integraciΓ³n. Esto le permitirΓ‘ comprender cΓ³mo estructurar sistemas modulares y distribuidos utilizando Lino.

Paso 3: Estructura generada

Tras ejecutar el comando y configurar las funciones, el CLI generarΓ‘ la estructura inicial del proyecto. Esta incluirΓ‘:

  • Carpetas para servicios y mΓ³dulos;
  • Plantillas para front-end (si aplica);
  • Configuraciones iniciales de cachΓ©, eventos e integraciones;
  • Archivos de soluciΓ³n (.slnx) y proyecto (.csproj) listos para compilar.

Ahora su proyecto MyApp estΓ‘ listo para recibir los servicios, mΓ³dulos, entidades y front-end que configuraremos en los siguientes pasos.

Agregando el frontend

Ahora vamos a crear la interfaz del sistema, el frontend, que se utilizarΓ‘ como Backoffice. Este frontend no serΓ‘ una aplicaciΓ³n pΓΊblica, sino una herramienta interna para que administradores y gestores puedan gestionar productos, categorΓ­as, inventarios, ventas y otra informaciΓ³n del sistema.

Paso 1: Ejecutando el comando de creaciΓ³n

Para agregar un nuevo frontend al proyecto, utiliza el siguiente comando en la terminal:

lino webapp new

El CLI solicitarΓ‘ alguna informaciΓ³n durante el proceso, como:

  • Nombre de la aplicaciΓ³n web: usaremos Backoffice para este ejemplo;

Paso 2: Estructura generada

Al finalizar el proceso, el CLI generarΓ‘ la estructura inicial del frontend dentro de la carpeta WebApps/Backoffice. La estructura predeterminada incluye:

  • Carpetas para pΓ‘ginas, componentes y servicios de la aplicaciΓ³n;
  • Clientes HTTP para consumir APIs de los servicios del proyecto;
  • Plantillas iniciales;
  • Archivos de configuraciΓ³n para la integraciΓ³n con autenticaciΓ³n, autorizaciΓ³n y eventos del sistema.

Notas importantes

  • El frontend se integrarΓ‘ automΓ‘ticamente con los servicios y mΓ³dulos seleccionados, permitiendo que los datos de productos, categorΓ­as y ventas se consuman directamente a travΓ©s de las APIs generadas por Lino.
  • Puedes crear mΓΊltiples frontends, por ejemplo, uno para administradores (Backoffice) y otro pΓΊblico (Sitio), siguiendo el mismo proceso.

Con el frontend creado, estamos listos para avanzar hacia la creaciΓ³n de los servicios y mΓ³dulos que proporcionarΓ‘n los datos y las reglas de negocio para esta aplicaciΓ³n.

CreaciΓ³n de servicios y mΓ³dulos

En esta etapa, construiremos los servicios y mΓ³dulos que compondrΓ‘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 manera independiente, manteniendo la cohesiΓ³n y facilitando el mantenimiento.

Paso 1: DefiniciΓ³n de los servicios

Inicialmente, crearemos los siguientes servicios, cada uno con responsabilidades bien definidas:

  • Catalog (modular) – responsable de la gestiΓ³n de productos, categorΓ­as y precios;
  • Sales – responsable del procesamiento de ventas y pedidos;
  • Stock – responsable de la gestiΓ³n de inventarios y movimientos;
  • Security – responsable de la autenticaciΓ³n, autorizaciΓ³n y gestiΓ³n de usuarios.

Para crear un nuevo servicio, ejecute el comando:

lino service new

Durante la ejecuciΓ³n del comando, el CLI solicitarΓ‘:

  • Nombre del servicio: por ejemplo, Catalog;
  • Base de datos: elija la tecnologΓ­a mΓ‘s adecuada para su proyecto (SQL Server, PostgreSQL, etc.);

Paso 2: CreaciΓ³n de mΓ³dulos dentro de los servicios

No todos los servicios necesitan ser modulares. En nuestro proyecto, solo el servicio Catalog tendrΓ‘ mΓ³dulos, para separar responsabilidades como merchandising y pricing.

Para el servicio Catalog, hemos definido los siguientes mΓ³dulos:

  • Merchandising – gestiΓ³n de productos y categorΓ­as;
  • Pricing – gestiΓ³n de precios, promociones e historial de cambios.

Para crear un mΓ³dulo, ejecute el comando:

lino module new

Puede crear tantos mΓ³dulos como desee 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 presentada aquΓ­ es solo con fines educativos y sirve como ejemplo de organizaciΓ³n modular.

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 de negocio, infraestructura y hosting;
  • Modules/: carpetas dentro de los servicios modulares, permitiendo organizar funcionalidades especΓ­ficas y mantener cΓ³digo cohesionado;
  • 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 manera independiente en diferentes partes del sistema, facilitando la escalabilidad, el mantenimiento y las pruebas.

Agregar autenticaciΓ³n y autorizaciΓ³n

La autenticaciΓ³n y la autorizaciΓ³n son elementos esenciales de cualquier sistema moderno. En Lino CLI, agregarlas a tu proyecto es simple y rΓ‘pido.

Paso 1: Ejecutar el comando de autenticaciΓ³n

Para agregar las funcionalidades de autenticaciΓ³n y autorizaciΓ³n, utiliza el comando:

lino features auth add

El CLI te guiarΓ‘ a travΓ©s de los siguientes pasos:

  • Elegir el servicio o mΓ³dulo: debes 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 y permisos, y configuraciΓ³n de polΓ­ticas de acceso.

Paso 2: Estructura generada

DespuΓ©s de ejecutar el comando, el servicio Security contendrΓ‘ archivos y carpetas como:

  • Entities: clases de usuarios, roles y permisos;
  • Infrastructure: configuraciones de base de datos y migraciones para crear tablas;
  • Application: servicios de autenticaciΓ³n, gestiΓ³n de usuarios y validaciΓ³n de credenciales;
  • API/Host: endpoints para inicio de sesiΓ³n, cierre de sesiΓ³n, registro y gestiΓ³n de roles.

Con esta configuraciΓ³n, tu aplicaciΓ³n tendrΓ‘ una autenticaciΓ³n robusta y un control de acceso granular, lista para soportar mΓΊltiples usuarios y diferentes niveles de permisos.

Agregando Background Jobs

En sistemas distribuidos y modulares, como el que estamos construyendo con el Lino CLI, no todos los servicios se comunican directamente entre sΓ­. Para garantizar la consistencia y confiabilidad en el intercambio de informaciΓ³n, utilizamos eventos de integraciΓ³n. Sin embargo, para procesar estos eventos de manera eficiente y asΓ­ncrona, necesitamos Background Jobs.

Lino utiliza el Outbox Pattern para garantizar que todos los mensajes generados por los servicios se registren de manera confiable antes de ser enviados. Con esto podemos:

  • Evitar la pΓ©rdida de eventos en caso de fallos o reinicios del servicio;
  • Garantizar que el mismo mensaje se envΓ­e solo una vez;
  • Permitir el reprocesamiento de mensajes en caso de fallo 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: Ejecutando el comando

Para agregar soporte de Background Jobs a tu proyecto, ejecuta el comando:

lino features background-job add

El CLI te pedirΓ‘ seleccionar el servicio donde se instalarΓ‘ el Background Job. Normalmente, elegirΓ‘s el servicio que centraliza la producciΓ³n de eventos, como Catalog o Sales.

Paso 2: Configurando la ejecuciΓ³n

Durante la configuraciΓ³n, podrΓ‘s definir:

  • Intervalo de verificaciΓ³n: determina con quΓ© frecuencia el Background Job revisarΓ‘ la tabla Outbox en busca de nuevos mensajes. Un intervalo muy corto puede aumentar el uso de recursos, mientras que uno largo puede retrasar la entrega de eventos;
  • Lote de registros procesados por vez: controla cuΓ‘ntos eventos se leerΓ‘n y enviarΓ‘n por ejecuciΓ³n. Lotes mΓ‘s grandes pueden aumentar el rendimiento, pero requieren mΓ‘s memoria y procesamiento;
  • PolΓ­tica de reintentos: en caso de fallo en la entrega de mensajes, puedes configurar cuΓ‘ntas veces el job intentarΓ‘ reenviar.

Estos parΓ‘metros dependen del tamaΓ±o de tu 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 contarΓ‘ con un Background Job listo para procesar mensajes de las tablas Outbox en cada servicio.

Esto garantiza que todos los eventos de integraciΓ³n se procesen de manera confiable y eficiente, permitiendo que mΓΊltiples servicios y mΓ³dulos se comuniquen de forma asΓ­ncrona sin afectar el rendimiento del sistema principal.

CreaciΓ³n de entidades y enumeraciones

En esta secciΓ³n, detallamos el diseΓ±o de las entidades, enumeraciones y objetos de valor de la aplicaciΓ³n, mostrando en quΓ© servicios y mΓ³dulos se crearΓ‘ cada elemento.

1. CreaciΓ³n de la entidad Category

Para crear la entidad, use el comando:

lino entity new

La entidad se crearΓ‘ en el servicio Catalog y en el mΓ³dulo Merchandising con la siguiente estructura:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PK β”‚ FK β”‚ Property name β”‚ Type   β”‚ Length β”‚ Required β”‚ Auto-increment β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ x  β”‚    β”‚ Id            β”‚ Guid   β”‚        β”‚    x     β”‚       x        β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚    β”‚    β”‚ Name          β”‚ string β”‚   50   β”‚    x     β”‚                β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. CreaciΓ³n de la entidad Product

A continuaciΓ³n, creamos la entidad Product en el mismo servicio y mΓ³dulo, incluyendo objetos de valor y enumeraciones:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 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 CreaciΓ³n del Value Object ProductDimension

Este Value Object representa las dimensiones del producto:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Property name β”‚ Type    β”‚ Length β”‚ Required β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Width         β”‚ decimal β”‚        β”‚    x     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Height        β”‚ decimal β”‚        β”‚    x     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Depth         β”‚ decimal β”‚        β”‚    x     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2.2 CreaciΓ³n del Enum ProductStatus

Este Enum define el estado del producto:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Value β”‚ Name         β”‚ Display Name β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1     β”‚ Active       β”‚ Active       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 2     β”‚ Inactive     β”‚ Inactive     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 3     β”‚ Discontinued β”‚ Discontinued β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. AΓ±adiendo nuevas propiedades

A medida que evoluciona el proyecto, podemos editar entidades existentes para aΓ±adir nuevas propiedades. Por ejemplo, aΓ±adiremos una lista de imΓ‘genes a la entidad Product:

lino entity edit

Al crear la propiedad Images del tipo List<ProductImage>, se generarΓ‘ la siguiente estructura:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 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 CreaciΓ³n de la entidad ProductImage

Esta entidad pertenece al agregado 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     β”‚                β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

4. CreaciΓ³n de entidades para otros servicios

En el servicio Sales, creamos la entidad ProductSnapshot, que se alimentarΓ‘ mediante eventos de integraciΓ³n. Como el Id original de la entidad Product proviene del servicio Catalog, no puede ser autoincrementable aquΓ­.

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PK β”‚ FK β”‚ Property name β”‚ Type    β”‚ Length β”‚ Required β”‚ Auto-increment β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ x  β”‚    β”‚ Id            β”‚ Guid    β”‚        β”‚    x     β”‚                β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚    β”‚    β”‚ Name          β”‚ string  β”‚  100   β”‚    x     β”‚                β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚    β”‚    β”‚ Price         β”‚ decimal β”‚        β”‚    x     β”‚                β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ObservaciΓ³n: solo se replicaron los campos esenciales en ProductSnapshot para el servicio Sales. Las entidades complementarias, como Customer, Order y StockItem, no se detallan aquΓ­ para simplificar la documentaciΓ³n.

Creando eventos y sus manejadores

Para recapitular, en el tema anterior creamos en el servicio modular Catalog.Merchandising las entidades Product, Category y ProductImage, mientras que en el servicio Sales creamos la entidad ProductSnapshot.

Ahora vamos a crear 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 a los servicios consumidores como Sales y Stock.

1. Creando eventos de dominio

El primer paso es crear los eventos de dominio ProductCreated y ProductUpdated con el comando:

lino event new

Durante la creaciΓ³n, podemos asociar el evento a un manejador y, al mismo tiempo, configurar el disparo 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 manera, 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);
  • Manejadores de eventos de dominio correspondientes;
  • Eventos de integraciΓ³n registrados automΓ‘ticamente en la Outbox por el manejador de eventos de dominio.

2. Creando manejadores de eventos de integraciΓ³n

El siguiente paso es definir quΓ© servicios consumirΓ‘n los eventos de integraciΓ³n. Para esto, usamos:

lino event-handler new

El flujo de creaciΓ³n incluye:

  • Seleccionar el servicio, mΓ³dulo y entidad que contendrΓ‘ el manejador;
  • Seleccionar el evento de integraciΓ³n que se consumirΓ‘ y de quΓ© servicio/mΓ³dulo/entidad proviene.

Por ejemplo, en el servicio Sales creamos los manejadores para ProductCreated y ProductUpdated que consumirΓ‘n los eventos disparados por 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    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

De este modo, tenemos dos manejadores de eventos de integraciΓ³n en el servicio Sales, consumiendo solo los campos necesarios de los eventos de integraciΓ³n del Catalog.Merchandising. Esto asegura que las tablas replicadas contengan ΓΊnicamente los datos esenciales, optimizando almacenamiento y rendimiento.

GeneraciΓ³n de 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. Para comenzar, simplemente ejecute el comando:

lino page new

Durante el proceso, usted:

  • SeleccionarΓ‘ el servicio, mΓ³dulo y entidad que desea exponer;
  • ElegirΓ‘ los campos que formarΓ‘n parte del listado;
  • GenerarΓ‘ automΓ‘ticamente pΓ‘ginas de listado (rejilla paginada) y formularios de creaciΓ³n/ediciΓ³n;
  • GenerarΓ‘ clases HttpClient para consumo en el frontend;
  • CrearΓ‘ todas las APIs REST necesarias (POST, PUT, PATCH, DELETE y GET);
  • CrearΓ‘ Commands y Queries con sus respectivos Handlers, que interactΓΊan con la base de datos garantizando el flujo completo de CRUD.

Con este comando, obtiene una aplicaciΓ³n funcional sin necesidad de escribir manualmente la capa de interfaz, APIs y lΓ³gica de negocio, manteniendo el estΓ‘ndar y la consistencia entre servicios.

Para este proyecto, podemos generar las pΓ‘ginas integradas para las siguientes entidades:

  • Catalog.Merchandising.Category
  • Catalog.Merchandising.Product
  • Sales.ProductSnapshot

Tras 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.

CreaciΓ³n de migraciones de bases de datos

Ahora que todas las entidades han sido creadas, es hora de generar las migraciones para que las bases de datos se creen o actualicen segΓΊn el modelo definido. Lino CLI automatiza este proceso, integrΓ‘ndose con Entity Framework y creando scripts listos para ejecutar.

Para crear una nueva migraciΓ³n, ejecute el comando:

lino database migrations new

Durante la ejecuciΓ³n, deberΓ‘:

  • Seleccionar el servicio y mΓ³dulo que recibirΓ‘n la migraciΓ³n;
  • Proporcionar una descripciΓ³n para la migraciΓ³n, por ejemplo, "Initial migration".

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 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 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Al confirmar, Lino CLI generarΓ‘:

  • Una nueva migraciΓ³n de base de datos para la versiΓ³n actual del servicio;
  • Un script SQL correspondiente, ubicado en la capa Infrastructure.Persistence, en la ruta /scripts/<version>/<nombre del archivo>;
  • El registro de la versiΓ³n de la migraciΓ³n en el historial del servicio, asegurando trazabilidad y consistencia.

Buenas prΓ‘cticas:

  • Crear nuevas migraciones siempre que haya cambios en el modelo de datos (nuevas entidades, propiedades o cambios en relaciones);
  • Revisar los scripts SQL generados antes de aplicarlos en producciΓ³n;
  • Mantener el control de versiones de la base de datos alineado con la versiΓ³n de la aplicaciΓ³n, evitando conflictos y problemas de sincronizaciΓ³n.

Siguiendo este flujo, se garantiza que la base de datos estΓ© siempre actualizada y consistente con el modelo de dominio definido en Lino CLI, reduciendo errores y simplificando el mantenimiento.

GeneraciΓ³n de imΓ‘genes Docker

DespuΓ©s de completar la generaciΓ³n del cΓ³digo para una versiΓ³n especΓ­fica, realizar pruebas e implementar todas las reglas de negocio necesarias, puede generar imΓ‘genes Docker de los servicios y aplicaciones web de su proyecto para su posterior publicaciΓ³n en un registro de contenedores.

Lino CLI simplifica este proceso con el comando:

lino build

Al ejecutarlo, 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 varios 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 patch (ej.: 0.1.0 β†’ 0.1.1);
  • Minor – incrementa la versiΓ³n menor (ej.: 0.1.0 β†’ 0.2.0);
  • Major – incrementa la versiΓ³n principal (ej.: 0.1.0 β†’ 1.0.0).

DespuΓ©s de seleccionar los servicios y definir el incremento de versiΓ³n, 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 etiqueta con la versiΓ³n definida;
  • Disponibilidad de las imΓ‘genes para publicaciΓ³n en su registro de contenedores.

Al final del proceso, considerando que todos los servicios y aplicaciones web fueron seleccionados, 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

ObservaciΓ³n: Este proceso garantiza consistencia 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 que cada servicio estΓ© aislado en contenedores independientes.

CreaciΓ³n de versiones en la aplicaciΓ³n

Incrementar nuevas versiones para los servicios o aplicaciones web es un proceso sencillo y centralizado en Lino CLI. Simplemente ejecute el comando:

lino version bump

Al igual que con la generaciΓ³n de imΓ‘genes Docker, al ejecutar este comando verΓ‘ una lista completa de todos los servicios y aplicaciones web de 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 funcionalidades compatibles con versiones anteriores;
  • Major – cambios que pueden romper la compatibilidad con versiones anteriores.

Es importante destacar que las versiones de los servicios y aplicaciones web tienen un impacto directo en:

  • Las etiquetas de las imΓ‘genes Docker;
  • Las carpetas utilizadas para almacenar scripts generados por las migraciones de la base de datos;
  • El control de releases y el historial del proyecto.

Con esto, concluimos la guΓ­a paso a paso de todos los comandos esenciales para la construcciΓ³n de un proyecto web utilizando Lino CLI, desde la instalaciΓ³n, creaciΓ³n de servicios, entidades, eventos y pΓ‘ginas, hasta la generaciΓ³n de imΓ‘genes Docker y el versionado.

No olvide seguir nuestro canal de YouTube para tutoriales detallados, demostraciones prΓ‘cticas y consejos sobre el uso de la herramienta, desde operaciones simples hasta funciones avanzadas.

Se ha producido un error no controlado. Recargar πŸ—™