도메인 모델링
λλ©μΈ μ£Όλ μ€κ³ μ ν리μΌμ΄μ μ ν΅μ¬μλ μμ€ν μ ν΅μ¬ μ§μκ³Ό λΉμ¦λμ€ κ·μΉμ λνλ΄λ λͺ¨λΈμ΄ μμ΅λλ€. λλ©μΈμ μ λͺ¨λΈλ§νλ€λ κ²μ νμ€ μΈκ³μ κ°λ μ ννλ ₯ μκ³ , μμ§λ ₯ μμΌλ©°, μΌκ΄μ± μλ μννΈμ¨μ΄ κ΅¬μ‘°λ‘ λ³ννλ κ²μ μλ―Έν©λλ€.
μν°ν°
μν°ν°λ μ£Όλ‘ μλ³μ±μΌλ‘ μ μλλ κ°μ²΄μ΄λ©° λ¨μν μμ±λ§μΌλ‘ μ μλμ§ μμ΅λλ€. μμ±μ΄ μκ°μ΄ μ§λλ©΄μ λ³κ²½λλλΌλ μν°ν°μ μλ³μ±μ λ³νμ§ μμ΅λλ€.
μ£Όμ νΉμ§:
- κ³ μ ν μλ³μ±(μΌλ°μ μΌλ‘
Id)μ κ°μ§λλ€. - μ€μν κ²μ μν°ν°κ° 무μμ ν¬ν¨νλμ§κ° μλλΌ λꡬμΈμ§μ λλ€.
- μμ±μ μκ°μ΄ μ§λλ©΄μ λ³κ²½λ μ μμ΅λλ€.
Linoλ‘ μν°ν° μμ±νκΈ°
Linoλ₯Ό μ¬μ©νμ¬ μ μν°ν°λ₯Ό μμ±νλ €λ©΄ λ€μμ μ€ννμΈμ:
lino entity new
CLI λμ°λ―Έκ° μμ²ν©λλ€:
- μλΉμ€ β μν°ν°κ° μμ±λ μλΉμ€μ λλ€.
- λͺ¨λ β μν°ν°κ° μμ±λ λͺ¨λ(λͺ¨λν μλΉμ€μλ§ ν΄λΉ).
- μν°ν° μ΄λ¦ β λλ©μΈκ³Ό λ°μ΄ν°λ² μ΄μ€ ν μ΄λΈμμ μ¬μ©λλ μ΄λ¦μ λλ€.
κ·Έ ν, κ° νλλ₯Ό μ€μ νμ¬ μν°ν°λ₯Ό ꡬμ±ν©λλ€.
μ¬μ© κ°λ₯ν νλ νμ
| νμ | μ€λͺ | λ²μ / μ°Έκ³ μ¬ν |
|---|---|---|
short | 16λΉνΈ μ μ | -32,768 β 32,767 |
int | 32λΉνΈ μ μ | -2,147,483,648 β 2,147,483,647 |
long | 64λΉνΈ μ μ | -9,223,372,036,854,775,808 β 9,223,372,036,854,775,807 |
string | ν μ€νΈ | μ½ 20μ΅ λ¬ΈμκΉμ§ |
bool | λΆλ¦¬μΈ κ° | true λλ false |
Guid | κΈλ‘λ² κ³ μ μλ³μ | λΆμ°λ κ³ μ μ± |
decimal | κ³ μ μμμ μ«μ | κΈμ΅ κ°μ μ ν© |
float | λΆλ μμμ μ«μ (32λΉνΈ) | μ½ 6β9μ리 μ λ°λ |
double | λΆλ μμμ μ«μ (64λΉνΈ) | μ½ 15β17μ리 μ λ°λ |
DateTime | λ μ§ λ° μκ° | μκ°λ ν¬ν¨ |
DateOnly | λ μ§λ§ (C# 10+) | β |
TimeOnly | μκ°λ§ (C# 10+) | β |
Entity | λ€λ₯Έ μν°ν° μ°Έμ‘° | 1 : 1 λλ 1 : N |
Value Object | λΆλ³ Value Object | μ: μ£Όμ, CPF |
Enum | μ΄κ±°ν | κ³ μ λ κ° μ§ν© |
List<Entity> | μν°ν° 리μ€νΈ | 1 : N |
ManyToMany | λ€λλ€ κ΄κ³ | μ‘°μΈ ν μ΄λΈ νμ |
μμ
Person μν°ν° μμ±νκΈ°:
ββββββ¬βββββ¬ββββββββββββββββ¬βββββββββ¬βββββββββ¬ββββββββββββ¬βββββββββββββββββ β PK β FK β Property name β Type β Length β Required β Auto-increment β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββΌβββββββββββββββββ€ β x β β Id β int β β x β x β ββββββΌβββββΌββββββββββββββββΌβββββββββΌβββββββββΌββββββββββββΌβββββββββββββββββ€ β β β Name β string β 100 β x β β ββββββ΄βββββ΄ββββββββββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ΄βββββββββββββββββ
Linoκ° μμ±ν ꡬ쑰:
<ProjectName>/
βββ src/
βββ Services/
βββ <ServiceName>/
βββ Domain/
βββ <ProjectName>.<ServiceName>.Domain.csproj
βββ Aggregates/
βββ People/
βββ Person.cs
βββ Errors/
β βββ PersonErrors.cs
βββ Repositories/
β βββ IPersonRepository.cs
βββ Resources/
βββ Person/
βββ PersonResources.resx
βββ PersonResources.en.resx
βββ PersonResources.pt-BR.resx
μν°ν°λ₯Ό μ μν ν, Linoλ₯Ό μ¬μ©νμ¬ Migrationsλ₯Ό κ΄λ¦¬νκ³ λ°μ΄ν°λ² μ΄μ€λ₯Ό λκΈ°ννμΈμ. μ΄ κ³Όμ μ Persistence Layer μΉμ μμ μμΈν λ€λ£° μμ μ λλ€.
νμ¬ μ§ν μν¬νλ‘
lino entity new λνν νλ¦ μΈμλ, μλΉμ€, λͺ¨λ, μ΄λ¦μ μ΄λ―Έ μκ³ μλ€λ©΄ CLI λͺ
λ Ήμμ μλλ₯Ό λͺ
μν μ μμ΅λλ€:
lino entity new --name <EntityName> --service <ServiceName> --module <ModuleName> lino entity edit --service <ServiceName> --module <ModuleName> --entity <EntityName> lino entity list --service <ServiceName> --module <ModuleName>
ν° λͺ¨λμμ μ κ°λ
μ λ§λ€κΈ° μ μ entity listλ₯Ό μ¬μ©νμμμ€. νΈμ§ μ€μλ μλ³μ, μμ±, νμ μ¬λΆ, κΈΈμ΄, κ΄κ³, μΈλ±μ€, ownership, tenant, migrations μν₯λλ₯Ό κ²ν ν©λλ€.
Strongly Typed IDs, ownership, invariants
Strongly Typed IDsκ° νμ±νλλ©΄ μλ³μλ ProductIdμ κ°μ μ μ© νμ
μ΄ λμ΄ μλ‘ λ€λ₯Έ μν°ν°μ IDsλ₯Ό μ€μλ‘ λ°κΎΈλ μΌμ μ€μ
λλ€. κ΄κ³λ μ€μ λλ©μΈ ownershipμ λ°μν΄μΌ ν©λλ€. λͺ¨λ μ°Έμ‘°κ° μ§μ νμμ΄ λ νμλ μμΌλ©°, λ§μ κ²½μ° μλ³μ, shadow entity, integration event λλ λͺ
μμ μΏΌλ¦¬κ° λͺ¨λ κ²½κ³λ₯Ό λ μ 보νΈν©λλ€.
invariantsλ UI, λ°μ΄ν°λ² μ΄μ€ λλ validatorsμλ§ λμ§ λ§κ³ λλ©μΈμ λμμμ€. μν°ν°λ₯Ό λ³κ²½ν νμλ buildλ₯Ό μ€ννκ³ diffλ₯Ό κ²ν ν λ€μ migrationsλ₯Ό μμ±νκ±°λ μ λ°μ΄νΈνμμμ€.
Value Object
Value Objectλ μ€μ§ μμ±λ€λ‘λ§ μ μλλ λλ©μΈ κ°λ μ λνλ΄λ©°, μ체μ μΈ μλ³μκ° μμ΅λλ€. λ Value Objectλ λͺ¨λ κ°μ΄ κ°μΌλ©΄ λμΌνλ€κ³ κ°μ£Όλ©λλ€.
μ£Όμ νΉμ§:
- μμ± ν λΆλ³μ λλ€.
Idκ° μμ΅λλ€.
Linoλ‘ Value Object μμ±νκΈ°
λ€μ λͺ λ Ήμ μ€ννμΈμ:
lino value-object new
CLIκ° λ€μμ μμ²ν©λλ€:
- μλΉμ€ β κ°μ²΄κ° μμ±λ μλΉμ€.
- λͺ¨λ β κ°μ²΄κ° μμ±λ λͺ¨λ(λͺ¨λν μλΉμ€μλ§ ν΄λΉ).
- μμΉ β λλ©μΈ λ£¨νΈ λλ νΉμ μ 그리κ²μ΄νΈ.
- Value Object μ΄λ¦.
κ·Έλ° λ€μ κ°μ²΄λ₯Ό ꡬμ±νλ νλλ₯Ό μ μνμΈμ.
μ¬μ© κ°λ₯ν νλ νμ
| νμ | μ€λͺ | λΉκ³ |
|---|---|---|
short | 16λΉνΈ μ μ | -32,768 β 32,767 |
int | 32λΉνΈ μ μ | -2,147,483,648 β 2,147,483,647 |
long | 64λΉνΈ μ μ | -9,223,372,036,854,775,808 β 9,223,372,036,854,775,807 |
string | ν μ€νΈ | μ½ 20μ΅ λ¬ΈμκΉμ§ |
bool | λΆλ¦¬μΈ | true/false |
decimal | μ νν μμμ μ«μ | κΈμ‘ κ° |
float | λΆλ μμμ μ«μ (32λΉνΈ) | μ½ 6~9μ리 |
double | λΆλ μμμ μ«μ (64λΉνΈ) | μ½ 15~17μ리 |
DateTime | λ μ§/μκ° | νμμ‘΄ ν¬ν¨ |
DateOnly | λ μ§λ§ | C# 10 μ΄μ |
TimeOnly | μκ°λ§ | C# 10 μ΄μ |
μμ
Value Object 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 β βββββββββββββββββ΄βββββββββ΄βββββββββ΄ββββββββββββ
μμ±λ νμΌ κ΅¬μ‘° (μ 그리κ²μ΄νΈ Person):
<ProjectName>/
βββ src/
βββ Services/
βββ <ServiceName>/
βββ Domain/
βββ <ProjectName>.<ServiceName>.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
μν°ν°μ λ§μ°¬κ°μ§λ‘ Migrationsλ Linoμ μν΄ κ΄λ¦¬λμ΄ λ°μ΄ν° λͺ¨λΈμ λκΈ°ν μνλ‘ μ μ§ν μ μμ΅λλ€.
νμ¬ μ§ν μν¬νλ‘
λνν λͺ λ Ή μΈμλ κ°λ μ μ΄λμ λ§λ€μ΄μΌ νλμ§ μ΄λ―Έ μκ³ μλ€λ©΄ νλΌλ―Έν°λ₯Ό μ¬μ©νμμμ€:
lino value-object new --name <ValueObjectName> --service <ServiceName> --module <ModuleName> lino value-object edit --service <ServiceName> --module <ModuleName> --value-object <ValueObjectName> lino value-object list --service <ServiceName> --module <ModuleName>
μν°ν° μμ±μ΄ ValueObjectλ‘ μ μΈλλ©΄ Linoλ μν°ν° λͺ¨λΈλ§ μ€ κΈ°μ‘΄ Value Objectλ₯Ό μ¬μ¬μ©νκ±°λ μλ‘ λ§λ€ μ μμ΅λλ€. νλ μ§ν©μ΄ κΈμ‘, μ£Όμ, μΉμ, κΈ°κ° λλ λ¬Έμμ²λΌ νλμ κ°λ
μ λνλΌ λ μ΄ μ΅μ
μ μ°μ νμμμ€.
μμμ±, UI λ° νμ§ν
Linoλ λͺ¨λμ μμμ± κ³μΈ΅μ ν΅ν΄ Value Objectsμ μμ±μ λ§€ννκ³ νμ λ©νλ°μ΄ν°λ₯Ό resourcesλ‘ μ λ¬ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ€μ²©λ κ°μ λν΄ νμ§νλ labelsμ λ©μμ§λ₯Ό μ 곡ν μ μμ΅λλ€. Value Objectλ μμ±λ λͺ¨λμ μνλ©°, λͺ μμ μΈ integration μμ΄λ λͺ¨λ κ° κ³΅μ κ³μ½μ΄ λμ§ μμ΅λλ€.
invariantsλ νμ μ체μμ 보νΈνμμμ€. μμ κ°, μλͺ»λ ν΅ν, λ€μ§ν κΈ°κ° λλ μλͺ»λ νμμ λ¬Έμκ° μ ν¨νκ² μμ±λμ΄μλ μ λ©λλ€.
μ΄κ±°ν
DDDμμ μ΄κ±°νμ C#μ μ ν΅μ μΈ enumμ λμ΄μ€ μ μμ΅λλ€. μνλ₯Ό νννλ νλΆν κ°μ²΄λ‘μ
μ ν¨μ± κ²μ¬, 보쑰 λ©μλ, μ¬μ§μ΄ λμκΉμ§ ν¬ν¨ν μ μμ΅λλ€.
λκΈ°:
- C#μ
enumμ μ μ λλ λ¬Έμμ΄ κ°μλ§ μ νλ©λλ€. - ν΄λμ€λ‘ μ΄κ±°νμ λͺ¨λΈλ§νλ©΄ λ ν° μ μ°μ±κ³Ό ννλ ₯μ μ 곡ν©λλ€.
μ£Όμ νΉμ§:
- κ³΅ν΅ κΈ°λ³Έ ν΄λμ€λ₯Ό μμνλ©°
Idμμ΄λ¦μ μΊ‘μννλ ν΄λμ€μ λλ€. - μ ν¨μ± κ²μ¬, 보쑰 λ©μλ λ° λμμ μΆκ°ν μ μμ΅λλ€.
Linoλ‘ μ΄κ±°ν μμ±νκΈ°
λ€μ λͺ λ Ήμ΄λ₯Ό μ€ννμΈμ:
lino enumeration new
λμλ§μ΄ λ€μμ μμ²ν©λλ€:
- μλΉμ€.
- λͺ¨λ (μ μ© κ°λ₯ν κ²½μ°).
- μμΉ β λλ©μΈ λ£¨νΈ λλ μ 그리κ²μ΄νΈ.
- μ΄κ±°ν μ΄λ¦.
- μ ν β μ ν΅μ μΈ
enumλλ μ€λ§νΈ Enum (class). - μ μ₯ λ°©μ β λ°μ΄ν°λ² μ΄μ€μμ
intλλstring.
μμ
PersonStatus μ΄κ±°ν:
βββββββββ¬ββββββββββββ¬βββββββββββββββ β Value β Name β Display Name β βββββββββΌββββββββββββΌβββββββββββββββ€ β 1 β Active β Active β βββββββββΌββββββββββββΌβββββββββββββββ€ β 2 β Inactive β Inactive β βββββββββΌββββββββββββΌβββββββββββββββ€ β 3 β Suspended β Suspended β βββββββββΌββββββββββββΌβββββββββββββββ€ β 4 β Deleted β Deleted β βββββββββ΄ββββββββββββ΄βββββββββββββββ
μμ±λ ꡬ쑰:
<ProjectName>/
βββ src/
βββ Services/
βββ <ServiceName>/
βββ Domain/
βββ <ProjectName>.<ServiceName>.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
μ΄κ±°ν κ°μ stringμΌλ‘ μ μ₯νλ κ²λ κ°λ₯νλ©° κ°λ
μ±μ λμΌ μ μμ§λ§,
μ±λ₯κ³Ό μ μ₯ κ³΅κ° λ©΄μμλ λ ν¨μ¨μ μΌ μ μμ΅λλ€.
λ°λΌμ κ°μ intλ‘ μ μ₯νκ³ , λ¬΄κ²°μ± μ μ§μ μ μ§λ³΄μλ₯Ό μ½κ² νκΈ° μν΄
μ΄κ±°ν κ°κ³Ό μΌμΉνλ κΈ°λ³Έ ν€λ₯Ό κ°μ§ 보쑰 μν°ν°(ν
μ΄λΈ)λ₯Ό μμ±νλ κ²μ κΆμ₯ν©λλ€.
μ΄κ±°νμ μ μν νμλ Linoλ₯Ό μ¬μ©νμ¬ Migrationsλ₯Ό μμ±νκ³ μ μ©νμ¬ λ°μ΄ν°λ² μ΄μ€κ° λλ©μΈ λͺ¨λΈμ λ°μνλλ‘ νμΈμ. μμΈν λ΄μ©μ μμμ± κ³μΈ΅ μΉμ μ μ°Έκ³ νμμμ€.
νμ¬ μ§ν μν¬νλ‘
λνν λͺ λ Ή μΈμλ μμΉμ μ΄λ¦μ΄ μ΄λ―Έ μ ν΄μ Έ μλ€λ©΄ νλΌλ―Έν°λ₯Ό μ¬μ©νμμμ€:
lino enumeration new --name <EnumerationName> --service <ServiceName> --module <ModuleName> lino enumeration edit --service <ServiceName> --module <ModuleName> --enumeration <EnumerationName> lino enumeration list --service <ServiceName> --module <ModuleName>
Enumeration, μν°ν° λλ μ€μ
| Enumeration μ¬μ© | μν°ν° λλ μ€μ μ¬μ© |
|---|---|
| μ£Όλ¬Έ μν, κ²μ μν, κΈ°μ μ ν΅ν© μ ν | μ¬μ©μκ° κ΄λ¦¬νλ μΉ΄ν κ³ λ¦¬, tenantλ³λ‘ μ€μ κ°λ₯ν μ¬μ , backofficeμμ κ΄λ¦¬λλ 곡κΈμ |
| μ½λμ ν¨κ» λ²μ κ΄λ¦¬λλ κ° | runtimeμ λ³κ²½λκ±°λ κΆνμΌλ‘ μ μ΄λλ κ° |
| κ°λ³ λ¨μ κ·μΉ λλ μμ λμ | λΌμ΄νμ¬μ΄ν΄, κ°μ¬, λμ λ²μ λλ μ체 κ΄κ³ |
Enumerationμ΄ νμ μ΄λ¦μ λ ΈμΆνλ©΄ Linoλ νμ§νλ labelsμ© resourcesλ₯Ό μμ±ν μ μμ΅λλ€. μ§μλκ±°λ seed dataλ‘ μ¬μ©λλ κ²½μ° κ°μ μΆκ°, μ κ±° λλ μ΄λ¦ λ³κ²½ν λ€ migrationsλ₯Ό κ²ν νμμμ€. μ½λ, λ°μ΄ν°λ² μ΄μ€, UI κ° μΌκ΄μ±λ λλ©μΈ λ³κ²½μ μΌλΆμ λλ€.
