Domänenmodellierung
Im Herzen jeder domΓ€nenorientierten Anwendung steht das Modell, das das zentrale Wissen und die GeschΓ€ftsregeln des Systems reprΓ€sentiert. Das DomΓ€nenmodell gut zu gestalten bedeutet, Konzepte der realen Welt in ausdrucksstarke, zusammenhΓ€ngende und konsistente Softwarestrukturen zu ΓΌbersetzen.
EntitΓ€ten
Eine EntitΓ€t ist ein Objekt, das hauptsΓ€chlich durch seine IdentitΓ€t definiert ist und nicht nur durch seine Attribute. Auch wenn sich die Attribute im Laufe der Zeit Γ€ndern, bleibt die IdentitΓ€t einer EntitΓ€t gleich.
Hauptmerkmale:
- Hat eine eindeutige IdentitΓ€t (normalerweise ein
Id
). - Wichtig ist, wer die EntitΓ€t ist, nicht nur was sie enthΓ€lt.
- Die Attribute kΓΆnnen sich im Laufe der Zeit Γ€ndern.
Erstellen einer EntitΓ€t mit Lino
Um eine neue EntitΓ€t mit Lino zu erstellen, fΓΌhren Sie aus:
lino entity new
Der CLI-Assistent fragt nach:
- Dienst β Dienst, in dem die EntitΓ€t erstellt wird.
- Modul β Modul, in dem die EntitΓ€t erstellt wird (nur bei modularen Diensten).
- EntitΓ€tsname β Name, der in der DomΓ€ne und der Datenbanktabelle verwendet wird.
Dann definieren Sie die Felder, aus denen die EntitΓ€t besteht, und konfigurieren jedes einzelne.
VerfΓΌgbare Feldtypen
Typ | Beschreibung | Bereich / Anmerkungen |
---|---|---|
short | 16-Bit Ganzzahl | -32β―768 β 32β―767 |
int | 32-Bit Ganzzahl | -2β―147β―483β―648 β 2β―147β―483β―647 |
long | 64-Bit Ganzzahl | -9β―223β―372β―036β―854β―775β―808 β 9β―223β―372β―036β―854β―775β―807 |
string | Text | Bis zu ~2 Milliarden Zeichen |
bool | Boolescher Wert | true oder false |
Guid | Eindeutiger globaler Bezeichner | Verteilte Eindeutigkeit |
decimal | Dezimalzahl mit hoher Genauigkeit | Ideal fΓΌr monetΓ€re Werte |
float | Gleitkommazahl (32 Bit) | β 6β9 Stellen Genauigkeit |
double | Gleitkommazahl (64 Bit) | β 15β17 Stellen Genauigkeit |
DateTime | Datum und Uhrzeit | Beinhaltet Zeitzone |
DateOnly | Nur Datum (C# 10+) | β |
TimeOnly | Nur Uhrzeit (C# 10+) | β |
Entity | Verweis auf eine andere EntitΓ€t | 1:1 oder 1:N |
Value Object | UnverΓ€nderliches Wertobjekt | z.B. Adresse, CPF |
Enum | AufzΓ€hlung | Feste Menge von Werten |
List<Entity> | Liste von EntitΓ€ten | 1:N |
ManyToMany | Viele-zu-viele | Erfordert VerknΓΌpfungstabelle |
Beispiel
Erstellen der EntitΓ€t Person
:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββ¬βββββββββ¬ββββββββββββ¬βββββββββββββββββ β PK β FK β Property name β Type β Length β Required β Auto-increment β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββΌβββββββββββββββββ€ β x β β Id β int β β x β x β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββΌβββββββββββββββββ€ β β β Name β string β 100 β x β β ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ΄βββββββββββββββββ
Vom Lino generierte Struktur:
MyApp/ βββ src/ βββ Services/ βββ MyService/ βββ Domain/ βββ MyApp.MyService.Domain.csproj βββ Aggregates/ βββ People/ βββ Person.cs βββ Errors/ β βββ PersonErrors.cs βββ Repositories/ β βββ IPersonRepository.cs βββ Resources/ βββ Person/ βββ PersonResources.resx βββ PersonResources.en.resx βββ PersonResources.pt-BR.resx
Nachdem Sie Ihre EntitΓ€ten definiert haben, verwenden Sie Lino, um die Migrations zu verwalten und die Datenbank synchron zu halten. Dieser Prozess wird im Abschnitt Persistenzschicht ausfΓΌhrlich behandelt.
Wertobjekte
Ein Wertobjekt reprΓ€sentiert ein DomΓ€nenkonzept, das ausschlieΓlich durch seine Attribute definiert wird β es besitzt keine eigene IdentitΓ€t. Zwei Wertobjekte gelten als gleich, wenn alle ihre Werte ΓΌbereinstimmen.
Hauptmerkmale:
- UnverΓ€nderlich nach der Erstellung.
- Besitzen keine
Id
.
Erstellen eines Wertobjekts mit Lino
FΓΌhren Sie aus:
lino value-object new
Das CLI wird fragen nach:
- Service β Service, in dem das Objekt erstellt wird.
- Modul β Modul, in dem das Objekt erstellt wird (nur in modularen Services).
- Ort β DomΓ€nenwurzel oder spezifisches Aggregat.
- Name des Wertobjekts.
Definieren Sie anschlieΓend die Felder, die das Objekt ausmachen.
VerfΓΌgbare Feldtypen
Typ | Beschreibung | Anmerkungen |
---|---|---|
short | 16-Bit-Ganzzahl | -32.768 β 32.767 |
int | 32-Bit-Ganzzahl | -2.147.483.648 β 2.147.483.647 |
long | 64-Bit-Ganzzahl | -9.223.372.036.854.775.808 β 9.223.372.036.854.775.807 |
string | Text | Bis zu ~2 Milliarden Zeichen |
bool | Boolean | true /false |
decimal | PrΓ€zise Dezimalzahl | MonetΓ€re Werte |
float | Gleitkommazahl (32 Bit) | β 6β9 Stellen |
double | Gleitkommazahl (64 Bit) | β 15β17 Stellen |
DateTime | Datum/Uhrzeit | EnthΓ€lt Zeitzone |
DateOnly | Nur Datum | C# 10+ |
TimeOnly | Nur Uhrzeit | C# 10+ |
Beispiel
Wertobjekt Address
:
βββββββββββββββββ¬βββββββββ¬βββββββββ¬ββββββββββββ β Property name β Type β Length β Required β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Street β string β 100 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Number β string β 10 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Neighborhood β string β 50 β β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β City β string β 100 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β State β string β 2 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β PostalCode β string β 20 β x β βββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββ€ β Country β string β 100 β x β βββββββββββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ
Generierte Dateistruktur (Aggregat Person
):
MyApp/ βββ src/ βββ Services/ βββ MyService/ βββ Domain/ βββ MyApp.MyService.Domain.csproj βββ Aggregates/ βββ People/ βββ Person.cs βββ ValueObjects/ β βββ Address.cs βββ Errors/ β βββ AddressErrors.cs β βββ PersonErrors.cs βββ Repositories/ β βββ IPersonRepository.cs βββ Resources/ βββ Address/ β βββ AddressResources.resx β βββ AddressResources.en.resx β βββ AddressResources.pt-BR.resx βββ Person/ βββ PersonResources.resx βββ PersonResources.en.resx βββ PersonResources.pt-BR.resx
Wie bei EntitΓ€ten kΓΆnnen Migrations von Lino verwaltet werden, um das Datenmodell synchron zu halten.
Enumeration
Enumeration in DDD kΓΆnnen ΓΌber die traditionellen enum
-Typen von C# hinausgehen. Sie kΓΆnnen reichhaltige Objekte sein,
die feste ZustΓ€nde reprΓ€sentieren, Validierungen, Hilfsmethoden und sogar Verhalten enthalten.
Motivation:
- Die C#-
enum
-Typen sind auf einen ganzzahligen oder string-Wert beschrΓ€nkt. - Das Modellieren einer Enumeration als Klasse bietet mehr FlexibilitΓ€t und Ausdruckskraft.
Hauptmerkmale:
- Es sind Klassen, die von einer gemeinsamen Basis erben und
Id
undName
kapseln. - Sie erlauben das HinzufΓΌgen von Validierungen, Hilfsmethoden und Verhalten.
Erstellen einer Enumeration mit Lino
FΓΌhren Sie aus:
lino enum new
Der Assistent wird nach Folgendem fragen:
- Service.
- Modul (falls zutreffend).
- Ort β Root des DomΓ€nens oder Aggregats.
- Name der Enumeration.
- Typ β traditionelles
enum
oder Smart Enum (class
). - Speicherung β
int
oderstring
in der Datenbank.
Beispiel
Enumeration PersonStatus
:
βββββββββ¬ββββββββββββ¬βββββββββββββββ β Value β Name β Display Name β βββββββββΌββββββββββββΌβββββββββββββββ€ β 1 β Active β Active β βββββββββΌββββββββββββΌβββββββββββββββ€ β 2 β Inactive β Inactive β βββββββββΌββββββββββββΌβββββββββββββββ€ β 3 β Suspended β Suspended β βββββββββΌββββββββββββΌβββββββββββββββ€ β 4 β Deleted β Deleted β βββββββββ΄ββββββββββββ΄βββββββββββββββ
Generierte Struktur:
MyApp/ βββ src/ βββ Services/ βββ MyService/ βββ Domain/ βββ MyApp.MyService.Domain.csproj βββ Aggregates/ βββ People/ βββ Person.cs βββ Enums/ β βββ PersonStatus.cs βββ ValueObjects/ β βββ Address.cs βββ Errors/ β βββ AddressErrors.cs β βββ PersonErrors.cs βββ Repositories/ β βββ IPersonRepository.cs βββ Resources/ βββ Address/ β βββ AddressResources.resx β βββ AddressResources.en.resx β βββ AddressResources.pt-BR.resx βββ Person/ β βββ PersonResources.resx β βββ PersonResources.en.resx β βββ PersonResources.pt-BR.resx βββ PersonStatus/ βββ PersonStatusResources.resx βββ PersonStatusResources.en.resx βββ PersonStatusResources.pt-BR.resx
Das Speichern des Werts einer Enumeration als string
ist gΓΌltig und kann die Lesbarkeit verbessern, ist jedoch in Bezug auf Leistung und Speicher ineffizienter.
Daher empfehlen wir, den Wert als int
zu speichern und zur Wahrung der referenziellen IntegritΓ€t und zur Vereinfachung der Wartung eine HilfsentitΓ€t (Tabelle) zu erstellen, bei der der PrimΓ€rschlΓΌssel dem Wert der Enumeration entspricht.
Nachdem Sie die Enumerationen definiert haben, verwenden Sie Lino, um die Migrations zu generieren und anzuwenden, damit die Datenbank das DomΓ€nenmodell widerspiegelt. Details finden Sie im Abschnitt Persistenzschicht.