Skip to content

Commit 832bc82

Browse files
authored
Merge pull request #116 from Royal-Code/releases/unit-of-work
Releases/unit of work
2 parents 4bdcf9f + 0bffd84 commit 832bc82

76 files changed

Lines changed: 2769 additions & 159 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/domain-nuget.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Setup .NET
1919
uses: actions/setup-dotnet@v4
2020
with:
21-
dotnet-version: '9.0.x'
21+
dotnet-version: '10.0.x'
2222
include-prerelease: true
2323

2424
- name: Build and pack Entities

.github/workflows/persistence-nuget.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Setup .NET
1919
uses: actions/setup-dotnet@v4
2020
with:
21-
dotnet-version: '9.0.x'
21+
dotnet-version: '10.0.x'
2222
include-prerelease: true
2323

2424
- name: Build and pack Repositories Abstractions
@@ -38,6 +38,15 @@ jobs:
3838

3939
- name: Build and pack Work Context EntityFramework
4040
run: dotnet build ./RoyalCode.EnterprisePatterns/RoyalCode.WorkContext.EntityFramework/RoyalCode.WorkContext.EntityFramework.csproj -c Release
41-
41+
42+
- name: Build and pack Work Context PostgreSql
43+
run: dotnet build ./RoyalCode.EnterprisePatterns/RoyalCode.WorkContext.PostgreSql/RoyalCode.WorkContext.PostgreSql.csproj -c Release
44+
45+
- name: Build and pack Work Context Sqlite
46+
run: dotnet build ./RoyalCode.EnterprisePatterns/RoyalCode.WorkContext.Sqlite/RoyalCode.WorkContext.Sqlite.csproj -c Release
47+
48+
- name: Build and pack Work Context SqlServer
49+
run: dotnet build ./RoyalCode.EnterprisePatterns/RoyalCode.WorkContext.SqlServer/RoyalCode.WorkContext.SqlServer.csproj -c Release
50+
4251
- name: Publish
4352
run: dotnet nuget push ./**/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# RoyalCode Enterprise Patterns – Domínio (Entities e Aggregates)
2+
3+
Este documento descreve as bibliotecas de domínio e foca em como modelar entidades e agregados, separando o conteúdo de persistência (WorkContext/UnitOfWork/Repositories), que está documentado em `.docs/workcontext.md`.
4+
5+
Escopo:
6+
- `RoyalCode.Entities`
7+
- `RoyalCode.Aggregates`
8+
9+
Compatibilidade: múltiplos targets (.NET 8, .NET 9 e .NET 10) via `$(LibTargets)`.
10+
11+
---
12+
13+
## RoyalCode.Entities
14+
15+
Fundação para modelagem de entidades. Fornece contratos e implementações básicas para ID, Code, Guid, estado ativo e exclusão lógica.
16+
17+
Principais tipos
18+
- `IEntity` / `IEntity<TId>`: marca uma entidade e o tipo do seu identificador.
19+
- `Entity<TId>`: base com propriedade `Id` (set protegido).
20+
- `Entity<TId, TCode>`: base com `Id` e `Code`.
21+
- `IHasId<TId>`: expõe `Id` para entidades/DTOs.
22+
- `IHasCode<TCode>`: expõe `Code` (identificador amigável e único, distinto do ID).
23+
- `IHasGuid`: expõe `Guid` global (não substitui o ID; útil para referência cruzada entre bancos/contextos).
24+
- `IActiveState`: expõe `IsActive` para habilitar/desabilitar sem deletar.
25+
- `ISoftDeletable`: expõe `IsDeleted` para exclusão lógica.
26+
27+
Referência rápida de API (como Copilot deve sugerir)
28+
- Criar entidade: `public class Product : Entity<Guid> { /* propriedades */ }`
29+
- Criar DTO associado: `public class ProductDto : IHasId<Guid> { public Guid Id {get;set;} /* ... */ }`
30+
- Entidade com código: `public class Sku : Entity<int, string> { /* Code já incluído */ }`
31+
32+
Quando usar
33+
- Herde de `Entity<TId>` para qualquer entidade de domínio com ID.
34+
- Use `Entity<TId, TCode>` quando existir também um código de negócio único.
35+
- Implemente `IHasGuid`, `IActiveState` e/ou `ISoftDeletable` conforme os requisitos do domínio.
36+
37+
Exemplo básico
38+
```csharp
39+
using RoyalCode.Entities;
40+
41+
public class Person : Entity<int>
42+
{
43+
public string Name { get; set; } = null!;
44+
}
45+
```
46+
47+
Exemplo com `Entity<TId, TCode>`
48+
```csharp
49+
using RoyalCode.Entities;
50+
51+
public class CatalogItem : Entity<Guid, string>
52+
{
53+
public string Name { get; set; } = null!;
54+
// Code é herdado e tem set protegido
55+
public CatalogItem(Guid id, string code, string name)
56+
{
57+
Id = id;
58+
Code = code;
59+
Name = name;
60+
}
61+
}
62+
```
63+
64+
---
65+
66+
## RoyalCode.Aggregates
67+
68+
Modelagem de Agregados (DDD). Define a raiz do agregado e integra a coleta de eventos de domínio.
69+
70+
Principais tipos
71+
- `IAggregateRoot` / `IAggregateRoot<TId>`: marca a raiz do agregado e o tipo do ID.
72+
- `AggregateRoot<TId>`: base que herda de `Entity<TId>` e inclui `IDomainEventCollection? DomainEvents` + método protegido `AddEvent(IDomainEvent)`.
73+
- `AggregateRoot<TId, TCode>`: versão com `Code` além do ID e dos eventos.
74+
75+
Eventos de domínio
76+
- `AggregateRoot<TId>` mantém uma coleção de eventos (`DomainEvents`).
77+
- Use `AddEvent(evt)` para registrar eventos quando invariantes do agregado forem alteradas.
78+
- O despacho/persistência de eventos é responsabilidade das bibliotecas de infraestrutura; aqui apenas coletamos os eventos.
79+
80+
Exemplo
81+
```csharp
82+
using RoyalCode.Aggregates;
83+
using RoyalCode.DomainEvents; // IDomainEvent
84+
85+
public sealed class Order : AggregateRoot<Guid>
86+
{
87+
public string Number { get; private set; }
88+
89+
public Order(string number)
90+
{
91+
Id = Guid.NewGuid();
92+
Number = number;
93+
AddEvent(new OrderCreated(Id, Number));
94+
}
95+
}
96+
97+
public record OrderCreated(Guid OrderId, string Number) : IDomainEvent;
98+
```
99+
100+
Exemplo com `AggregateRoot<TId, TCode>`
101+
```csharp
102+
using RoyalCode.Aggregates;
103+
using RoyalCode.DomainEvents;
104+
105+
public sealed class ProductAggregate : AggregateRoot<Guid, string>
106+
{
107+
public string Name { get; private set; }
108+
109+
public ProductAggregate(string code, string name)
110+
{
111+
Id = Guid.NewGuid();
112+
Code = code;
113+
Name = name;
114+
AddEvent(new ProductCreated(Id, Code));
115+
}
116+
}
117+
118+
public record ProductCreated(Guid ProductId, string Code) : IDomainEvent;
119+
```
120+
121+
---
122+
123+
## Boas práticas de modelagem
124+
- Mantenha invariantes do agregado dentro da raiz (`AggregateRoot`) e dispare eventos com `AddEvent` após mudanças significativas.
125+
- Não exponha `set` público para `Id`/`Code`; proteja modificações via comportamentos.
126+
- Utilize `IHasGuid` quando precisar correlacionar a mesma entidade em múltiplos bancos/contextos.
127+
- Prefira `ISoftDeletable` e `IActiveState` para cenários de (des)ativação e exclusão lógica.
128+
129+
Para integração com persistência, consulte `.docs/workcontext.md`.
130+

RoyalCode.EnterprisePatterns/.docs/instructions-for-copilot.md

Whitespace-only changes.

0 commit comments

Comments
 (0)