Von null bis Build: Schritt-für-Schritt-Anleitung

Dieses Thema bietet eine praktische Schritt-fΓΌr-Schritt-Anleitung zur Verwendung von Lino CLI als Hauptwerkzeug beim Aufbau eines Projekts: von der Installation und ersten Konfiguration ΓΌber die Generierung von Services, Modulen und EntitΓ€ten bis hin zu fortgeschrittenen Funktionen wie Ereignissen, Hintergrundjobs, Migrationen, Docker-Image-Builds und Versionsverwaltung.


Ziel ist es, aufzuzeigen, wie die CLI-Befehle in den realen Entwicklungsfluss integriert werden β€” nicht nur sie aufzulisten, sondern den Grund jeder Wahl zu erklΓ€ren, was automatisch generiert wird und welche architektonischen Auswirkungen dies hat.


Auch wenn jeder Befehl bereits eigene Dokumentation hat, sehen Sie hier den End-to-End-Prozess β€” ein reproduzierbares Vorgehen, das Stunden wiederholter Arbeit spart und hilft, konsistenten und testbaren Code zu pflegen.


Im Verlauf des Guides erklΓ€ren wir technische Konzepte, die Lino anwendet (z.β€―B.: CQRS, TypedResults, Source Generators, Outbox Pattern), zeigen Beispiele fΓΌr Befehle und geben Best Practices fΓΌr Versionierung, Deployment und Continuous Integration an.

Installation und Konfiguration von Lino CLI

Der erste Schritt, um mit Lino CLI zu arbeiten, besteht darin, das Tool in Ihrer Entwicklungsumgebung zu installieren. Es wird als dotnet Global Tool bereitgestellt, was bedeutet, dass es fΓΌr jedes .NET-Projekt auf Ihrem Computer verfΓΌgbar ist.

Schritt 1: Installation

Um Lino CLI zu installieren (oder zu aktualisieren), fΓΌhren Sie den folgenden Befehl im Terminal aus:

dotnet tool install --global Tolitech.Lino

Wichtige Hinweise:

  • Wenn bereits eine Version installiert ist, kΓΆnnen Sie dotnet tool update --global Tolitech.Lino verwenden, um sie zu aktualisieren.
  • Stellen Sie sicher, dass das Verzeichnis fΓΌr globale .NET-Tools im System-PATH enthalten ist, damit der Befehl lino korrekt funktioniert.

Schritt 2: Sprache einstellen

Nach der Installation wird empfohlen, die Sprache (oder Kultur) zu konfigurieren, die das CLI fΓΌr Nachrichten, Eingabeaufforderungen und Logs verwenden soll:

lino preferences culture set

Sie werden aufgefordert, eine der verfΓΌgbaren Sprachen auszuwΓ€hlen. Diese Einstellung stellt sicher, dass alle Anweisungen und Aufforderungen konsistent in der gewΓΌnschten Sprache angezeigt werden.

Schritt 3: Authentifizierung und Registrierung

Um auf alle Funktionen von Lino zuzugreifen, einschließlich erweiterter Vorlagen, Docker-Image-Publikationen und Integration mit externen Diensten, ist eine Authentifizierung erforderlich.

- Falls Sie noch kein Konto haben, registrieren Sie sich mit folgendem Befehl:

lino user register

- Falls Sie bereits ein Konto haben, melden Sie sich mit folgendem Befehl an:

lino auth login

Was passiert: Das CLI speichert ein Authentifizierungstoken lokal, sodass Sie Befehle ausfΓΌhren kΓΆnnen, die Zugriff auf geschΓΌtzte Ressourcen erfordern, ohne sich jedes Mal anmelden zu mΓΌssen.

Schritt 4: Überprüfung

Um zu bestΓ€tigen, dass Installation und Authentifizierung erfolgreich waren, fΓΌhren Sie aus:

lino --version

Wenn der Befehl die installierte Version zurΓΌckgibt, sind Sie bereit, Lino CLI in Ihren Projekten zu verwenden.

Erstellen des Projekts MyApp

In diesem Schritt erstellen wir die anfΓ€ngliche Projektstruktur mithilfe von Lino CLI. Dieses Projekt dient als Basis, um die Erstellung von Services, Modulen, Front-End und die Integration von Events zu demonstrieren.

Schritt 1: AusfΓΌhren des Erstellungsbefehls

Um ein neues Projekt zu erstellen, fΓΌhren Sie den folgenden Befehl im Terminal aus:

lino project new

Das CLI fΓΌhrt Sie Schritt fΓΌr Schritt und fragt dabei nach Informationen wie:

  • Projektname: wir verwenden MyApp, Sie kΓΆnnen jedoch jeden beliebigen Namen wΓ€hlen;
  • ZusΓ€tzliche Funktionen: Code-Analysetools, verteiltes Caching, UnterstΓΌtzung fΓΌr asynchrone Events usw.

Schritt 2: Konfigurieren der Kernfunktionen

FΓΌr dieses Projekt empfehlen wir, die folgenden Funktionen von Anfang an zu aktivieren:

  • Code-Analysetools: stellen sicher, dass der Code Best Practices und konsistente Standards einhΓ€lt und hΓ€ufige Implementierungsfehler verhindert;
  • Verteiltes Caching: verbessert die Anwendungsleistung in Multi-Service-Szenarien und verhindert unnΓΆtige Datenbankabfragen;
  • Asynchrone Kommunikation: ermΓΆglicht die Nutzung von Events und Queues fΓΌr die Integration zwischen Services und gewΓ€hrleistet Skalierbarkeit und Entkopplung.

Es ist wichtig, alle diese Optionen in diesem Projekt zu aktivieren, da wir mehrere Services erstellen werden, die ΓΌber Integrations-Events kommunizieren. Dies ermΓΆglicht es Ihnen, zu verstehen, wie modulare und verteilte Systeme mit Lino strukturiert werden.

Schritt 3: Generierte Struktur

Nach AusfΓΌhrung des Befehls und Konfiguration der Funktionen generiert das CLI die anfΓ€ngliche Projektstruktur. Diese umfasst:

  • Ordner fΓΌr Services und Module;
  • Templates fΓΌr Front-End (falls zutreffend);
  • Anfangskonfigurationen fΓΌr Cache, Events und Integrationen;
  • LΓΆsungsdateien (.slnx) und Projektdateien (.csproj), bereit zur Kompilierung.

Ihr Projekt MyApp ist nun bereit, die Services, Module, EntitΓ€ten und das Front-End zu erhalten, die wir in den nΓ€chsten Schritten konfigurieren werden.

HinzufΓΌgen des Frontends

Nun erstellen wir die SystemoberflΓ€che, das Frontend, das als Backoffice verwendet wird. Dieses Frontend wird keine ΓΆffentliche Anwendung sein, sondern ein internes Tool, mit dem Administratoren und Manager Produkte, Kategorien, BestΓ€nde, VerkΓ€ufe und andere Systeminformationen verwalten kΓΆnnen.

Schritt 1: AusfΓΌhren des Erstellungskommandos

Um dem Projekt ein neues Frontend hinzuzufΓΌgen, verwenden Sie den folgenden Befehl im Terminal:

lino webapp new

Die CLI wird wΓ€hrend des Prozesses einige Informationen abfragen, wie zum Beispiel:

  • Name der Webanwendung: fΓΌr dieses Beispiel verwenden wir Backoffice;

Schritt 2: Generierte Struktur

Am Ende des Prozesses erstellt die CLI die anfΓ€ngliche Frontend-Struktur im Ordner WebApps/Backoffice. Die Standardstruktur umfasst:

  • Ordner fΓΌr Seiten, Komponenten und Dienste der Anwendung;
  • HTTP-Clients zum Konsumieren von APIs der Projektdienste;
  • Startvorlagen;
  • Konfigurationsdateien fΓΌr die Integration mit Authentifizierung, Autorisierung und Systemereignissen.

Wichtige Hinweise

  • Das Frontend wird automatisch mit den ausgewΓ€hlten Diensten und Modulen integriert, sodass Produkt-, Kategorien- und Verkaufsdaten direkt ΓΌber die von Lino generierten APIs konsumiert werden kΓΆnnen.
  • Sie kΓΆnnen mehrere Frontends erstellen, zum Beispiel eines fΓΌr Administratoren (Backoffice) und ein weiteres ΓΆffentliches (Site), indem Sie denselben Prozess befolgen.

Mit dem erstellten Frontend sind wir bereit, mit der Erstellung der Dienste und Module fortzufahren, die die Daten und GeschΓ€ftsregeln fΓΌr diese Anwendung bereitstellen werden.

Erstellen von Services und Modulen

In diesem Schritt werden wir die Services und Module erstellen, die die Anwendung bilden. Ziel ist es, eine modulare und skalierbare Architektur zu schaffen, die es verschiedenen Bereichen des Systems, wie Produkte, Kategorien, Lager, Vertrieb und Medien, ermΓΆglicht, sich unabhΓ€ngig weiterzuentwickeln, wΓ€hrend KohΓ€sion erhalten und Wartung erleichtert wird.

Schritt 1: Definition der Services

ZunΓ€chst erstellen wir die folgenden Services, jeder mit klar definierten Verantwortlichkeiten:

  • Catalog (modular) – verantwortlich fΓΌr die Verwaltung von Produkten, Kategorien und Preisen;
  • Sales – verantwortlich fΓΌr die Verarbeitung von VerkΓ€ufen und Bestellungen;
  • Stock – verantwortlich fΓΌr die Verwaltung von LagerbestΓ€nden und Bewegungen;
  • Security – verantwortlich fΓΌr Authentifizierung, Autorisierung und Benutzerverwaltung.

Um einen neuen Service zu erstellen, fΓΌhren Sie folgenden Befehl aus:

lino service new

WΓ€hrend der AusfΓΌhrung des Befehls fragt das CLI:

  • Service-Name: z.B. Catalog;
  • Datenbank: wΓ€hlen Sie die Technologie, die am besten zu Ihrem Projekt passt (SQL Server, PostgreSQL, etc.);

Schritt 2: Erstellen von Modulen innerhalb der Services

Nicht alle Services mΓΌssen modular sein. In unserem Projekt hat nur der Service Catalog Module, um Verantwortlichkeiten wie Merchandising und Pricing zu trennen.

FΓΌr den Service Catalog haben wir die folgenden Module definiert:

  • Merchandising – Verwaltung von Produkten und Kategorien;
  • Pricing – Verwaltung von Preisen, Aktionen und Γ„nderungsverlΓ€ufen.

Um ein Modul zu erstellen, fΓΌhren Sie folgenden Befehl aus:

lino module new

Sie kΓΆnnen beliebig viele Module innerhalb des modularen Services Catalog erstellen. AbhΓ€ngig von der KomplexitΓ€t kΓΆnnten einige Module zukΓΌnftig eigenstΓ€ndige Services werden. Die hier gezeigte Aufteilung dient nur zu Schulungszwecken und als Beispiel fΓΌr modulare Organisation.

Endstruktur des Projekts

Nach der Erstellung der Services und Module sollte Ihre LΓΆsung eine Struktur wie folgt haben:

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/

ErklΓ€rung der Struktur:

  • Services/: enthΓ€lt alle Services des Systems, jeder isoliert mit eigener GeschΓ€ftslogik, Infrastruktur und Hosting;
  • Modules/: Ordner innerhalb der modularen Services, zur Organisation spezifischer Funktionen und zur Wahrung des zusammenhΓ€ngenden Codes;
  • WebApps/: Frontends, die mit dem System verbunden sind und bereits in die Services integriert sind;
  • Shared/: Bibliotheken und Ressourcen, die zwischen Services und Frontends geteilt werden;
  • tests/: Unit- und Integrationstests, organisiert nach Service und Modul.

Mit dieser modularen Struktur kann jedes Team oder jeder Entwickler unabhΓ€ngig an verschiedenen Teilen des Systems arbeiten, wodurch Skalierbarkeit, Wartung und Tests erleichtert werden.

HinzufΓΌgen von Authentifizierung und Autorisierung

Authentifizierung und Autorisierung sind wesentliche Elemente jedes modernen Systems. Im Lino CLI ist das HinzufΓΌgen zu Ihrem Projekt einfach und schnell.

Schritt 1: AusfΓΌhren des Authentifizierungsbefehls

Um Authentifizierungs- und Autorisierungsfunktionen hinzuzufΓΌgen, verwenden Sie den Befehl:

lino features auth add

Das CLI fΓΌhrt Sie durch die folgenden Schritte:

  • Auswahl des Dienstes oder Moduls: Sie mΓΌssen angeben, wo die Authentifizierungsartefakte installiert werden. In unserem Beispielprojekt verwenden wir den Security-Dienst, der die gesamte Sicherheitslogik des Systems zentralisiert;
  • ZusΓ€tzliche Konfigurationen: Erstellen von Tabellen fΓΌr Benutzer, Rollen und Berechtigungen sowie Konfiguration von Zugriffspolicen.

Schritt 2: Generierte Struktur

Nach AusfΓΌhrung des Befehls enthΓ€lt der Security-Dienst Dateien und Ordner wie:

  • Entities: Klassen fΓΌr Benutzer, Rollen und Berechtigungen;
  • Infrastructure: Datenbankkonfigurationen und Migrationen zum Erstellen der Tabellen;
  • Application: Authentifizierungsdienste, Benutzerverwaltung und Validierung von Anmeldeinformationen;
  • API/Host: Endpunkte fΓΌr Login, Logout, Registrierung und Rollenverwaltung.

Mit dieser Einrichtung verfΓΌgt Ihre Anwendung ΓΌber eine robuste Authentifizierung und granulare Zugriffskontrolle, bereit zur UnterstΓΌtzung mehrerer Benutzer und unterschiedlicher Berechtigungsebenen.

HinzufΓΌgen von Background Jobs

In verteilten und modularen Systemen, wie dem, das wir mit dem Lino CLI erstellen, kommunizieren nicht alle Dienste direkt miteinander. Um Konsistenz und ZuverlΓ€ssigkeit beim Informationsaustausch zu gewΓ€hrleisten, verwenden wir Integrationsereignisse. Um diese Ereignisse jedoch effizient und asynchron zu verarbeiten, benΓΆtigen wir Background Jobs.

Lino verwendet das Outbox Pattern, um sicherzustellen, dass alle von den Diensten generierten Nachrichten zuverlΓ€ssig erfasst werden, bevor sie gesendet werden. Damit kΓΆnnen wir:

  • Verlust von Ereignissen bei DienstausfΓ€llen oder Neustarts vermeiden;
  • Garantieren, dass dieselbe Nachricht nur einmal gesendet wird;
  • Die erneute Verarbeitung von Nachrichten bei Zustellungsfehlern ermΓΆglichen;
  • Die Verarbeitung von Ereignissen von der Hauptlogik der Anwendung trennen, was Leistung und Skalierbarkeit verbessert.

Schritt 1: AusfΓΌhren des Befehls

Um UnterstΓΌtzung fΓΌr Background Jobs in Ihrem Projekt hinzuzufΓΌgen, fΓΌhren Sie den Befehl aus:

lino features background-job add

Das CLI fordert Sie auf, den Dienst auszuwΓ€hlen, in dem der Background Job installiert werden soll. In der Regel wΓ€hlen Sie den Dienst, der die Ereigniserzeugung zentralisiert, z. B. Catalog oder Sales.

Schritt 2: Konfiguration der AusfΓΌhrung

WΓ€hrend der Konfiguration kΓΆnnen Sie Folgendes festlegen:

  • ÜberprΓΌfungsintervall: Bestimmt, wie hΓ€ufig der Background Job die Outbox-Tabelle auf neue Nachrichten ΓΌberprΓΌft. Ein zu kurzes Intervall kann die Ressourcennutzung erhΓΆhen, wΓ€hrend ein zu langes Intervall die Zustellung der Ereignisse verzΓΆgern kann;
  • Batchgrâße der zu verarbeitenden EintrΓ€ge: Steuert, wie viele Ereignisse pro AusfΓΌhrung gelesen und gesendet werden. Grâßere Batches kΓΆnnen die Leistung erhΓΆhen, erfordern jedoch mehr Speicher und Rechenleistung;
  • Retry-Politik: Bei einer fehlgeschlagenen NachrichtenΓΌbermittlung kΓΆnnen Sie festlegen, wie oft der Job einen erneuten Sendeversuch unternimmt.

Diese Parameter hÀngen von der Grâße Ihres Systems, der LeistungsfÀhigkeit der Maschine und dem erwarteten Ereignisvolumen ab.

Schritt 3: Generierte Struktur

Nach der Konfiguration verfΓΌgt das Projekt ΓΌber einen Background Job, der Nachrichten aus den Outbox-Tabellen in jedem Dienst verarbeiten kann.

So wird sichergestellt, dass alle Integrationsereignisse zuverlΓ€ssig und effizient verarbeitet werden, wodurch mehrere Dienste und Module asynchron kommunizieren kΓΆnnen, ohne die Leistung des Hauptsystems zu beeintrΓ€chtigen.

Erstellen von EntitΓ€ten und Enumerationen

In diesem Abschnitt beschreiben wir detailliert das Design der EntitΓ€ten, Enumerationen und Value Objects der Anwendung und zeigen, in welchen Services und Modulen jedes Element erstellt wird.

1. Erstellen der EntitΓ€t Category

Um die EntitΓ€t zu erstellen, verwenden Sie den Befehl:

lino entity new

Die EntitΓ€t wird im Service Catalog und im Modul Merchandising mit der folgenden Struktur erstellt:

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

2. Erstellen der EntitΓ€t Product

Anschließend erstellen wir die EntitÀt Product im gleichen Service und Modul, einschließlich Value Objects und Enumerationen:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 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 Erstellen des Value Objects ProductDimension

Dieses Value Object reprΓ€sentiert die Dimensionen des Produkts:

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

2.2 Erstellen des Enums ProductStatus

Dieses Enum definiert den Status des Produkts:

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

3. HinzufΓΌgen neuer Eigenschaften

Mit der Weiterentwicklung des Projekts kΓΆnnen bestehende EntitΓ€ten bearbeitet werden, um neue Eigenschaften hinzuzufΓΌgen. Zum Beispiel fΓΌgen wir der EntitΓ€t Product eine Liste von Bildern hinzu:

lino entity edit

Beim Erstellen der Eigenschaft Images vom Typ List<ProductImage> entsteht die folgende Struktur:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 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 Erstellen der EntitΓ€t ProductImage

Diese EntitΓ€t gehΓΆrt zum Aggregat Product und hat die folgende Struktur:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 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. Erstellen von EntitΓ€ten fΓΌr andere Services

Im Service Sales erstellen wir die EntitΓ€t ProductSnapshot, die durch Integrationsereignisse befΓΌllt wird. Da die ursprΓΌngliche Id der EntitΓ€t Product aus dem Service Catalog stammt, kann sie hier nicht auto-increment sein.

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

Hinweis: Es wurden nur die wesentlichen Felder in ProductSnapshot fΓΌr den Service Sales repliziert. ErgΓ€nzende EntitΓ€ten wie Customer, Order und StockItem werden hier nicht detailliert beschrieben, um die Dokumentation zu vereinfachen.

Erstellen von Events und deren Handlern

Zur Zusammenfassung: Im vorherigen Abschnitt haben wir im modularen Service Catalog.Merchandising die EntitΓ€ten Product, Category und ProductImage erstellt, wΓ€hrend wir im Service Sales die EntitΓ€t ProductSnapshot erstellt haben.

Jetzt erstellen wir Domain-Events und Integrations-Events. Das Ziel ist, dass beim Erstellen oder Aktualisieren von Produkten im Service Catalog diese Γ„nderungen an die konsumierenden Services wie Sales und Stock repliziert werden.

1. Erstellen von Domain-Events

Der erste Schritt besteht darin, die Domain-Events ProductCreated und ProductUpdated mit folgendem Befehl zu erstellen:

lino event new

WΓ€hrend der Erstellung kΓΆnnen Sie das Event einem Handler zuordnen und gleichzeitig das AuslΓΆsen eines Integrations-Events konfigurieren. Dadurch wird die Erstellung des gesamten notwendigen Ablaufs zentralisiert.

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

Auf die gleiche Weise erstellen wir das Event 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                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Damit haben wir:

  • Domain-Events erstellt (ProductCreated und ProductUpdated);
  • Entsprechende Domain-Event-Handler;
  • Integrations-Events automatisch in der Outbox durch den Domain-Event-Handler registriert.

2. Erstellen von Integrations-Event-Handlern

Der nΓ€chste Schritt besteht darin, festzulegen, welche Services die Integrations-Events konsumieren. DafΓΌr verwenden wir:

lino event-handler new

Der Erstellungsprozess umfasst:

  • Auswahl des Service, Moduls und der EntitΓ€t, die den Handler enthalten wird;
  • Auswahl des zu konsumierenden Integrations-Events und von welchem Service/Modul/EntitΓ€t es stammt.

Zum Beispiel erstellen wir im Service Sales die Handler fΓΌr ProductCreated und ProductUpdated, die die Events des Catalog.Merchandising.Product konsumieren:

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

Somit haben wir zwei Integrations-Event-Handler im Service Sales, die nur die notwendigen Felder aus den Integrations-Events von Catalog.Merchandising konsumieren. Dies stellt sicher, dass die replizierten Tabellen nur die wesentlichen Daten enthalten und Speicherplatz sowie Performance optimiert werden.

Erstellen von Webseiten, APIs, Commands und Queries

Einer der großen Vorteile von Lino CLI ist die Mâglichkeit, Webseiten, APIs, Commands und Queries automatisiert zu erstellen, wodurch der gesamte Entwicklungsfluss vereinfacht wird. Um zu beginnen, führen Sie einfach den folgenden Befehl aus:

lino page new

WΓ€hrend des Prozesses werden Sie:

  • Dienst, Modul und EntitΓ€t auswΓ€hlen, die Sie bereitstellen mΓΆchten;
  • Die Felder auswΓ€hlen, die in der Liste enthalten sein sollen;
  • Automatisch Listenseiten (paginierte Grid-Ansicht) und Erstellungs-/Bearbeitungsformulare generieren;
  • HttpClient-Klassen fΓΌr die Nutzung im Frontend generieren;
  • Alle erforderlichen REST-APIs erstellen (POST, PUT, PATCH, DELETE und GET);
  • Commands und Queries mit den entsprechenden Handlers erstellen, die mit der Datenbank interagieren und den vollstΓ€ndigen CRUD-Fluss gewΓ€hrleisten.

Mit diesem Befehl erhalten Sie eine funktionale Anwendung, ohne die BenutzeroberflΓ€che, APIs und GeschΓ€ftslogik manuell schreiben zu mΓΌssen, wobei die Standards und Konsistenz zwischen den Diensten erhalten bleiben.

FΓΌr dieses Projekt kΓΆnnen wir die integrierten Seiten fΓΌr die folgenden EntitΓ€ten generieren:

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

Nach der Generierung von Seiten, APIs und Commands/Queries ist die Anwendung bereit fΓΌr eine vollstΓ€ndige Interaktion zwischen Frontend und Backend, wobei Validierungen, Routen und Persistenz bereits automatisch vom Lino CLI konfiguriert werden.

Datenbank-Migrationen erstellen

Nun, da alle EntitΓ€ten erstellt wurden, ist es an der Zeit, Migrationen zu generieren, damit die Datenbanken entsprechend dem definierten Modell erstellt oder aktualisiert werden. Lino CLI automatisiert diesen Prozess, integriert sich in Entity Framework und erstellt ausfΓΌhrbare Skripte.

Um eine neue Migration zu erstellen, fΓΌhren Sie den folgenden Befehl aus:

lino database migrations new

WΓ€hrend der AusfΓΌhrung mΓΌssen Sie:

  • Den Service und das Modul auswΓ€hlen, die die Migration erhalten sollen;
  • Eine Beschreibung fΓΌr diese Migration angeben, z. B. "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 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Nach der BestΓ€tigung generiert Lino CLI:

  • Eine neue Datenbank-Migration fΓΌr die aktuelle Service-Version;
  • Ein entsprechendes SQL-Skript, das im Layer Infrastructure.Persistence unter dem Pfad /scripts/<version>/<Dateiname> abgelegt wird;
  • Die Registrierung der Migrationsversion im Service-Verlauf, wodurch Nachverfolgbarkeit und Konsistenz gewΓ€hrleistet werden.

Best Practices:

  • Erstellen Sie neue Migrationen, wenn Γ„nderungen am Datenmodell vorgenommen werden (neue EntitΓ€ten, Eigenschaften oder Γ„nderungen der Beziehungen);
  • ÜberprΓΌfen Sie die generierten SQL-Skripte, bevor Sie sie in der Produktion anwenden;
  • Halten Sie die Datenbank-Versionierung mit der Anwendungs-Version synchron, um Konflikte und Synchronisationsprobleme zu vermeiden.

Durch das Befolgen dieses Prozesses stellen Sie sicher, dass die Datenbank stets aktuell und konsistent mit dem in Lino CLI definierten DomΓ€nenmodell ist, wodurch Fehler reduziert und die Wartung vereinfacht wird.

Docker-Images erstellen

Nach Abschluss der Codegenerierung fΓΌr eine bestimmte Version, DurchfΓΌhrung von Tests und Implementierung aller erforderlichen GeschΓ€ftsregeln kΓΆnnen Sie Docker-Images fΓΌr die Services und Webanwendungen Ihres Projekts erstellen, um sie spΓ€ter in einem Container-Registry zu verΓΆffentlichen.

Lino CLI vereinfacht diesen Prozess mit dem Befehl:

lino build

Bei der AusfΓΌhrung sehen Sie eine Liste aller im Projekt verfΓΌgbaren Services und Webanwendungen sowie deren aktuelle Versionen:

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|

Sie kΓΆnnen einen oder mehrere Services und Webanwendungen auswΓ€hlen, um Images gleichzeitig zu erstellen. Markieren Sie einfach die gewΓΌnschten Elemente.

Anschließend werden Sie aufgefordert auszuwÀhlen, wie die Version der erstellten Images aktualisiert werden soll. Die verfügbaren Optionen sind:

  • Aktuelle Version beibehalten – Γ€ndert die bestehende Version nicht;
  • Patch – erhΓΆht die Patch-Version (z. B.: 0.1.0 β†’ 0.1.1);
  • Minor – erhΓΆht die Minor-Version (z. B.: 0.1.0 β†’ 0.2.0);
  • Major – erhΓΆht die Major-Version (z. B.: 0.1.0 β†’ 1.0.0).

Nach der Auswahl der Services und Festlegung der VersionserhΓΆhung fΓΌhrt Lino CLI Folgendes aus:

  • Build des Codes jedes Services und jeder Webanwendung;
  • Erstellung des entsprechenden Docker-Images;
  • Anwendung des Tags mit der definierten Version;
  • Bereitstellung der Images zur VerΓΆffentlichung in Ihrem Container-Registry.

Am Ende des Prozesses, vorausgesetzt alle Services und Webanwendungen wurden ausgewΓ€hlt, haben die erzeugten Images die folgende Struktur:

  • 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

Hinweis: Dieser Prozess gewΓ€hrleistet die Konsistenz zwischen Code und Docker-Image-Versionen, erleichtert den Deploy und die Wartung mehrerer Umgebungen und ermΓΆglicht es, jeden Service in unabhΓ€ngigen Containern isoliert auszufΓΌhren.

Versionen in der Anwendung erstellen

Das ErhΓΆhen neuer Versionen fΓΌr Services oder Webanwendungen ist ein einfacher und zentralisierter Prozess in Lino CLI. FΓΌhren Sie einfach den folgenden Befehl aus:

lino version bump

Wie bei der Erstellung von Docker-Images sehen Sie beim AusfΓΌhren dieses Befehls eine vollstΓ€ndige Liste aller Services und Webanwendungen Ihres Projekts. Nur die ausgewΓ€hlten Elemente werden versioniert, die ΓΌbrigen bleiben unverΓ€ndert.

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|

Nach der Auswahl der gewΓΌnschten Elemente werden Sie aufgefordert, den Typ der VersionserhΓΆhung auszuwΓ€hlen. Die verfΓΌgbaren Optionen sind:

  • Patch – kleine Korrekturen ohne funktionale Auswirkungen;
  • Minor – HinzufΓΌgen neuer Funktionen, die mit frΓΌheren Versionen kompatibel sind;
  • Major – Γ„nderungen, die die KompatibilitΓ€t mit frΓΌheren Versionen brechen kΓΆnnen.

Es ist wichtig zu beachten, dass die Versionen von Services und Webanwendungen direkten Einfluss haben auf:

  • Die Tags der Docker-Images;
  • Die Ordner, die zum Speichern von durch Datenbankmigrationen generierten Skripten verwendet werden;
  • Das Release-Management und die Projekt-Historie.

Damit schließen wir die Schritt-für-Schritt-Anleitung zu allen wesentlichen Befehlen für den Aufbau eines Webprojekts mit Lino CLI ab, von der Installation, Erstellung von Services, EntitÀten, Events und Seiten bis hin zur Erstellung von Docker-Images und Versionierung.

Vergessen Sie nicht, unseren YouTube-Kanal zu abonnieren, um detaillierte Tutorials, praktische Demonstrationen und Tipps zur Nutzung des Tools zu erhalten – von einfachen Operationen bis hin zu erweiterten Funktionen.

Ein unbehandelter Fehler ist aufgetreten. Aktualisieren πŸ—™