Skip to content

Commit 11ff7d2

Browse files
committed
add transactional outbox (dapr) #5
1 parent e3c0b9e commit 11ff7d2

File tree

49 files changed

+545
-142
lines changed

Some content is hidden

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

49 files changed

+545
-142
lines changed

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,59 @@ public interface IDeleteCommand<TId, TResponse> : ICommand<TResponse> where TId
188188
}
189189
```
190190

191+
# Service Invocation
192+
193+
- RestEase with Dapr handler. More information is at https://dev.to/thangchung/how-to-make-dapr-client-works-well-with-refit-and-restease-40m
194+
195+
# Event Bus
196+
197+
```csharp
198+
public interface IEventBus
199+
{
200+
Task PublishAsync<TEvent>(TEvent @event, string[] topics = default, CancellationToken token = default) where TEvent : IDomainEvent;
201+
202+
Task SubscribeAsync<TEvent>(string[] topics = default, CancellationToken token = default) where TEvent : IDomainEvent;
203+
}
204+
```
205+
206+
- Dapr provider
207+
208+
# Transactional Outbox
209+
210+
```csharp
211+
public class OutboxEntity
212+
{
213+
[JsonInclude]
214+
public Guid Id { get; private set; }
215+
216+
[JsonInclude]
217+
public DateTime OccurredOn { get; private set; }
218+
219+
[JsonInclude]
220+
public string Type { get; private set; }
221+
222+
[JsonInclude]
223+
public string Data { get; private set; }
224+
225+
public OutboxEntity()
226+
{
227+
// only for System.Text.Json to deserialized data
228+
}
229+
230+
public OutboxEntity(Guid id, DateTime occurredOn, IDomainEvent @event)
231+
{
232+
Id = id.Equals(Guid.Empty) ? Guid.NewGuid() : id;
233+
OccurredOn = occurredOn;
234+
Type = @event.GetType().FullName;
235+
Data = JsonConvert.SerializeObject(@event);
236+
}
237+
238+
public virtual IDomainEvent RecreateMessage(Assembly assembly) => (IDomainEvent)JsonConvert.DeserializeObject(Data, assembly.GetType(Type)!);
239+
}
240+
```
241+
242+
- Dapr provider
243+
191244
# Sample pages
192245

193246
![](assets/products_screen.png)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: dapr.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: CustomerOutboxCron
5+
spec:
6+
type: bindings.cron
7+
metadata:
8+
- name: schedule
9+
value: "@every 5s"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: dapr.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: ProductOutboxCron
5+
spec:
6+
type: bindings.cron
7+
metadata:
8+
- name: schedule
9+
value: "@every 5s"

coolstore.sln

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomerService.Application
5454
EndProject
5555
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gateways", "Gateways", "{4DE0371F-85C0-4CC2-8457-08EB3F3F0A4D}"
5656
EndProject
57-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppGateway", "src\Gateways\AppGateway\AppGateway.csproj", "{8CFC9025-2F85-4196-9AE7-74FE68AB79A4}"
57+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppGateway", "src\Gateways\AppGateway\AppGateway.csproj", "{8CFC9025-2F85-4196-9AE7-74FE68AB79A4}"
58+
EndProject
59+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoolStore.IntegrationEvents", "src\BuildingBlocks\CoolStore.IntegrationEvents\CoolStore.IntegrationEvents.csproj", "{AD80375D-9465-4137-BB48-8D05A6FEB8F3}"
5860
EndProject
5961
Global
6062
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -122,6 +124,10 @@ Global
122124
{8CFC9025-2F85-4196-9AE7-74FE68AB79A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
123125
{8CFC9025-2F85-4196-9AE7-74FE68AB79A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
124126
{8CFC9025-2F85-4196-9AE7-74FE68AB79A4}.Release|Any CPU.Build.0 = Release|Any CPU
127+
{AD80375D-9465-4137-BB48-8D05A6FEB8F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
128+
{AD80375D-9465-4137-BB48-8D05A6FEB8F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
129+
{AD80375D-9465-4137-BB48-8D05A6FEB8F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
130+
{AD80375D-9465-4137-BB48-8D05A6FEB8F3}.Release|Any CPU.Build.0 = Release|Any CPU
125131
EndGlobalSection
126132
GlobalSection(SolutionProperties) = preSolution
127133
HideSolutionNode = FALSE
@@ -142,6 +148,7 @@ Global
142148
{A26F7B4F-F725-4018-954A-C3D7925C2A30} = {5D18FF27-2948-433A-A40F-77C778A705C1}
143149
{4F623591-01CB-4CCE-9BDD-9B0CBC6D8F8E} = {5D18FF27-2948-433A-A40F-77C778A705C1}
144150
{8CFC9025-2F85-4196-9AE7-74FE68AB79A4} = {4DE0371F-85C0-4CC2-8457-08EB3F3F0A4D}
151+
{AD80375D-9465-4137-BB48-8D05A6FEB8F3} = {B17CF9E5-E4A8-42B4-A669-7BC41D314D5F}
145152
EndGlobalSection
146153
GlobalSection(ExtensibilityGlobals) = postSolution
147154
SolutionGuid = {7B983152-0931-4714-9EDE-BD7DE35C758E}

src/BuildingBlocks/CoolStore.AppContracts/CoolStore.AppContracts.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net5.0</TargetFramework>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace CoolStore.IntegrationEvents
2+
{
3+
public struct Anchor
4+
{
5+
}
6+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
<LangVersion>preview</LangVersion>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\N8T.Core\N8T.Core.csproj" />
11+
<ProjectReference Include="..\N8T.Infrastructure\N8T.Infrastructure.csproj" />
12+
</ItemGroup>
13+
14+
</Project>

src/BuildingBlocks/CoolStore.AppContracts/IntegrationEvents/CustomerCreatedIntegrationEvent.cs renamed to src/BuildingBlocks/CoolStore.IntegrationEvents/Customer/CustomerCreatedIntegrationEvent.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
using N8T.Core.Domain;
22
using N8T.Infrastructure.Bus.Dapr;
33

4-
namespace CoolStore.AppContracts.IntegrationEvents
4+
namespace CoolStore.IntegrationEvents.Customer
55
{
66
[DaprPubSubName(PubSubName = "pubsub")]
7-
public class CustomerCreatedIntegrationEvent : IntegrationEventBase
7+
public class CustomerCreatedIntegrationEvent : EventBase
88
{
99
public override void Flatten()
1010
{
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using N8T.Core.Domain;
3+
4+
namespace CoolStore.IntegrationEvents.Product
5+
{
6+
public class ProductCodeCreatedIntegrationEvent : EventBase
7+
{
8+
public Guid ProductCodeId { get; set; }
9+
public string ProductCodeName { get; set; } = default!;
10+
11+
public override void Flatten()
12+
{
13+
MetaData.Add("ProductCodeId", ProductCodeId);
14+
MetaData.Add("ProductCodeName", ProductCodeName);
15+
}
16+
}
17+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using N8T.Core.Domain;
3+
4+
namespace CoolStore.IntegrationEvents.Product
5+
{
6+
public class ProductCreatedIntegrationEvent : EventBase
7+
{
8+
public Guid Id { get; set; }
9+
public string Name { get; set; } = default!;
10+
public int Quantity { get; set; }
11+
public Guid ProductCodeId { get; set; }
12+
public decimal ProductCost { get; set; }
13+
14+
public override void Flatten()
15+
{
16+
MetaData.Add("ProductId", Id);
17+
MetaData.Add("ProductName", Name);
18+
MetaData.Add("ProductQuantity", Quantity);
19+
MetaData.Add("ProductCode", ProductCodeId);
20+
MetaData.Add("ProductCost", ProductCost);
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)