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.Linoverwenden, um sie zu aktualisieren. - Stellen Sie sicher, dass das Verzeichnis fΓΌr globale .NET-Tools im System-
PATHenthalten ist, damit der Befehllinokorrekt 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 (
ProductCreatedundProductUpdated); - 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.
