Skip to content

Commit 24d3de3

Browse files
authored
Added Getting Started section with sample (#133)
* Refactored sample * Added TransactionalBox.Sample.WebApi.InMemory * Added Getting Started section in docs * Refactored sample for learning
1 parent 980c69e commit 24d3de3

File tree

13 files changed

+313
-9
lines changed

13 files changed

+313
-9
lines changed

TransactionalBox.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionalBox.InboxWorke
9595
EndProject
9696
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionalBox.Inbox.Storage.InMemory", "source\TransactionalBox.Inbox.Storage.InMemory\TransactionalBox.Inbox.Storage.InMemory.csproj", "{1BF21145-4651-40BD-897A-0CDFB2913FA6}"
9797
EndProject
98+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TransactionalBox.Sample.WebApi.InMemory", "samples\TransactionalBox.Sample.WebApi.InMemory\TransactionalBox.Sample.WebApi.InMemory.csproj", "{5C2EB157-F976-42F9-8B26-42A50898714C}"
99+
EndProject
98100
Global
99101
GlobalSection(SolutionConfigurationPlatforms) = preSolution
100102
Debug|Any CPU = Debug|Any CPU
@@ -273,6 +275,10 @@ Global
273275
{1BF21145-4651-40BD-897A-0CDFB2913FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
274276
{1BF21145-4651-40BD-897A-0CDFB2913FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
275277
{1BF21145-4651-40BD-897A-0CDFB2913FA6}.Release|Any CPU.Build.0 = Release|Any CPU
278+
{5C2EB157-F976-42F9-8B26-42A50898714C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
279+
{5C2EB157-F976-42F9-8B26-42A50898714C}.Debug|Any CPU.Build.0 = Debug|Any CPU
280+
{5C2EB157-F976-42F9-8B26-42A50898714C}.Release|Any CPU.ActiveCfg = Release|Any CPU
281+
{5C2EB157-F976-42F9-8B26-42A50898714C}.Release|Any CPU.Build.0 = Release|Any CPU
276282
EndGlobalSection
277283
GlobalSection(SolutionProperties) = preSolution
278284
HideSolutionNode = FALSE
@@ -321,6 +327,7 @@ Global
321327
{F1A53222-8BB9-45A7-8DC6-3050E1908C87} = {8FC46C4A-3C0C-458F-ACF5-F35F728A2988}
322328
{AC95B0C2-49E0-4A20-AF37-447D1ECA96AC} = {8FC46C4A-3C0C-458F-ACF5-F35F728A2988}
323329
{1BF21145-4651-40BD-897A-0CDFB2913FA6} = {8FC46C4A-3C0C-458F-ACF5-F35F728A2988}
330+
{5C2EB157-F976-42F9-8B26-42A50898714C} = {D018E603-5AE9-4B1B-BF33-04EB0B5D6913}
324331
EndGlobalSection
325332
GlobalSection(ExtensibilityGlobals) = postSolution
326333
SolutionGuid = {2D01E2B0-80D8-4BCE-BE98-29AC821F4F2B}

documentation/docs/getting-started.md

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,105 @@ sidebar_position: 2
44

55
# Getting Started
66

7-
Let's discover **TransactionalBox in less than 5 minutes**.
7+
Let's discover **TransactionalBox in less than 5 minutes**.
8+
Don't worry about the number of packages and if you don't understand something. I will try to introduce you step by step to the transactional box.
89

9-
## Installation
10+
## Configuration
11+
### Install packages
12+
```csharp
13+
dotnet add package TransactionalBox.Outbox.Storage.InMemory
14+
dotnet add package TransactionalBox.OutboxWorker.Storage.InMemory
15+
dotnet add package TransactionalBox.OutboxWorker.Transport.InMemory
16+
dotnet add package TransactionalBox.InboxWorker.Transport.InMemory
17+
dotnet add package TransactionalBox.InboxWorker.Storage.InMemory
18+
dotnet add package TransactionalBox.Inbox.Storage.InMemory
19+
```
20+
### Register
21+
```csharp
22+
using TransactionalBox;
23+
using TransactionalBox.Outbox;
24+
using TransactionalBox.Outbox.Storage.InMemory;
25+
using TransactionalBox.OutboxWorker;
26+
using TransactionalBox.OutboxWorker.Storage.InMemory;
27+
using TransactionalBox.OutboxWorker.Transport.InMemory;
28+
using TransactionalBox.InboxWorker;
29+
using TransactionalBox.InboxWorker.Transport.InMemory;
30+
using TransactionalBox.InboxWorker.Storage.InMemory;
31+
using TransactionalBox.Inbox;
32+
using TransactionalBox.Inbox.Storage.InMemory;
33+
```
1034

11-
TODO Examples
35+
```csharp
36+
builder.Services.AddTransactionalBox(x =>
37+
{
38+
x.AddOutbox(storage => storage.UseInMemory())
39+
.WithWorker(
40+
storage => storage.UseInMemory(),
41+
transport => transport.UseInMemory());
42+
43+
x.AddInbox(storage => storage.UseInMemory())
44+
.WithWorker(
45+
storage => storage.UseInMemory(),
46+
transport => transport.UseInMemory());
47+
},
48+
settings => settings.ServiceId = "ServiceName");
49+
```
50+
## Usage
51+
### Outbox
52+
#### Declare outbox message
53+
```csharp
54+
public sealed class ExampleMessage : IOutboxMessage
55+
{
56+
public string Name { get; init; }
57+
58+
public int Age { get; init; }
59+
}
60+
```
61+
#### Add message to outbox (to send)
62+
63+
```csharp
64+
public sealed class AddMessageToOutbox
65+
{
66+
private readonly IOutbox _outbox;
67+
68+
public AddMessageToOutbox(IOutbox outbox)
69+
{
70+
_outbox = outbox;
71+
}
72+
73+
public async Task Example()
74+
{
75+
var message = new ExampleMessage()
76+
{
77+
Name = "Name",
78+
Age = 25,
79+
};
80+
81+
await _outbox.Add(message, envelope => envelope.Receiver = "ServiceName");
82+
}
83+
}
84+
```
85+
86+
### Inbox
87+
#### Declare inbox message
88+
```csharp
89+
public sealed class ExampleMessage : IInboxMessage
90+
{
91+
public string Name { get; init; }
92+
93+
public int Age { get; init; }
94+
}
95+
```
96+
#### Handle message
97+
98+
```csharp
99+
internal sealed class ExampleMessageHandler : IInboxMessageHandler<ExampleMessage>
100+
{
101+
public async Task Handle(ExampleMessage message, IExecutionContext executionContext)
102+
{
103+
// Your Logic
104+
}
105+
}
106+
```
107+
## Summary
108+
Follow the workflow of your code with breakpoints. Enjoy learning :stuck_out_tongue_winking_eye:.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using TransactionalBox;
2+
using TransactionalBox.Outbox;
3+
using TransactionalBox.Outbox.Storage.InMemory;
4+
using TransactionalBox.OutboxWorker;
5+
using TransactionalBox.OutboxWorker.Storage.InMemory;
6+
using TransactionalBox.OutboxWorker.Transport.InMemory;
7+
using TransactionalBox.InboxWorker;
8+
using TransactionalBox.InboxWorker.Transport.InMemory;
9+
using TransactionalBox.InboxWorker.Storage.InMemory;
10+
using TransactionalBox.Inbox;
11+
using TransactionalBox.Inbox.Storage.InMemory;
12+
using TransactionalBox.Base.Inbox.Storage.InMemory;
13+
using TransactionalBox.Base.Outbox.Storage.InMemory;
14+
using Microsoft.AspNetCore.Mvc;
15+
using TransactionalBox.Sample.WebApi.InMemory.ServiceWithOutbox;
16+
17+
var builder = WebApplication.CreateBuilder(args);
18+
19+
builder.Services.AddEndpointsApiExplorer();
20+
builder.Services.AddSwaggerGen();
21+
builder.Services.AddScoped<ExampleServiceWithOutbox>();
22+
23+
builder.Services.AddTransactionalBox(x =>
24+
{
25+
x.AddOutbox(storage => storage.UseInMemory())
26+
.WithWorker(
27+
storage => storage.UseInMemory(),
28+
transport => transport.UseInMemory());
29+
30+
x.AddInbox(storage => storage.UseInMemory())
31+
.WithWorker(
32+
storage => storage.UseInMemory(),
33+
transport => transport.UseInMemory());
34+
},
35+
settings => settings.ServiceId = "ServiceName");
36+
37+
var app = builder.Build();
38+
39+
// Configure the HTTP request pipeline.
40+
if (app.Environment.IsDevelopment())
41+
{
42+
app.UseSwagger();
43+
app.UseSwaggerUI();
44+
}
45+
46+
app.UseHttpsRedirection();
47+
48+
app.MapPost("/add-message-to-outbox", async (ExampleServiceWithOutbox exampleServiceWithOutbox) => await exampleServiceWithOutbox.Execute());
49+
50+
app.MapGet("/get-messages-from-outbox", async (IOutboxStorageReadOnly outboxStorageReadOnly) => outboxStorageReadOnly.OutboxMessages);
51+
52+
app.MapGet("/get-messages-from-inbox", async (IInboxStorageReadOnly inboxStorage) => inboxStorage.InboxMessages);
53+
54+
app.MapGet("/get-idempotent-messages-from-inbox", async (IInboxStorageReadOnly inboxStorage) => inboxStorage.IdempotentInboxKeys);
55+
56+
app.Run();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"iisSettings": {
4+
"windowsAuthentication": false,
5+
"anonymousAuthentication": true,
6+
"iisExpress": {
7+
"applicationUrl": "http://localhost:1454",
8+
"sslPort": 44334
9+
}
10+
},
11+
"profiles": {
12+
"http": {
13+
"commandName": "Project",
14+
"dotnetRunMessages": true,
15+
"launchBrowser": true,
16+
"launchUrl": "swagger",
17+
"applicationUrl": "http://localhost:5152",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
},
22+
"https": {
23+
"commandName": "Project",
24+
"dotnetRunMessages": true,
25+
"launchBrowser": true,
26+
"launchUrl": "swagger",
27+
"applicationUrl": "https://localhost:7070;http://localhost:5152",
28+
"environmentVariables": {
29+
"ASPNETCORE_ENVIRONMENT": "Development"
30+
}
31+
},
32+
"IIS Express": {
33+
"commandName": "IISExpress",
34+
"launchBrowser": true,
35+
"launchUrl": "swagger",
36+
"environmentVariables": {
37+
"ASPNETCORE_ENVIRONMENT": "Development"
38+
}
39+
}
40+
}
41+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using TransactionalBox.Inbox;
2+
3+
namespace TransactionalBox.Sample.WebApi.InMemory.ServiceWithInbox
4+
{
5+
public sealed class ExampleMessage : IInboxMessage
6+
{
7+
public string Name { get; init; }
8+
9+
public int Age { get; init; }
10+
}
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using TransactionalBox.Inbox;
2+
using TransactionalBox.Inbox.Contexts;
3+
4+
namespace TransactionalBox.Sample.WebApi.InMemory.ServiceWithInbox
5+
{
6+
internal sealed class ExampleMessageHandler : IInboxMessageHandler<ExampleMessage>
7+
{
8+
public async Task Handle(ExampleMessage message, IExecutionContext executionContext)
9+
{
10+
// Your Logic
11+
}
12+
}
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using TransactionalBox.Outbox;
2+
3+
namespace TransactionalBox.Sample.WebApi.InMemory.ServiceWithOutbox
4+
{
5+
public sealed class ExampleMessage : IOutboxMessage
6+
{
7+
public string Name { get; init; }
8+
9+
public int Age { get; init; }
10+
}
11+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using TransactionalBox.Outbox;
2+
3+
namespace TransactionalBox.Sample.WebApi.InMemory.ServiceWithOutbox
4+
{
5+
public sealed class ExampleServiceWithOutbox
6+
{
7+
private readonly IOutbox _outbox;
8+
9+
public ExampleServiceWithOutbox(IOutbox outbox)
10+
{
11+
_outbox = outbox;
12+
}
13+
14+
public async Task Execute()
15+
{
16+
var message = new ExampleMessage()
17+
{
18+
Name = "Name",
19+
Age = 25,
20+
};
21+
22+
await _outbox.Add(message, envelope => envelope.Receiver = "ServiceName");
23+
}
24+
}
25+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<InvariantGlobalization>true</InvariantGlobalization>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
12+
<PackageReference Include="Swashbuckle.AspNetCore" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\..\source\TransactionalBox.Inbox.Storage.InMemory\TransactionalBox.Inbox.Storage.InMemory.csproj" />
17+
<ProjectReference Include="..\..\source\TransactionalBox.InboxWorker.Storage.InMemory\TransactionalBox.InboxWorker.Storage.InMemory.csproj" />
18+
<ProjectReference Include="..\..\source\TransactionalBox.InboxWorker.Transport.InMemory\TransactionalBox.InboxWorker.Transport.InMemory.csproj" />
19+
<ProjectReference Include="..\..\source\TransactionalBox.Outbox.Storage.InMemory\TransactionalBox.Outbox.Storage.InMemory.csproj" />
20+
<ProjectReference Include="..\..\source\TransactionalBox.OutboxWorker.Storage.InMemory\TransactionalBox.OutboxWorker.Storage.InMemory.csproj" />
21+
<ProjectReference Include="..\..\source\TransactionalBox.OutboxWorker.Transport.InMemory\TransactionalBox.OutboxWorker.Transport.InMemory.csproj" />
22+
</ItemGroup>
23+
24+
</Project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*"
9+
}

samples/TransactionalBox.Sample.WebApi/InboxMessages/ExampleMessageHandler.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ namespace TransactionalBox.Sample.WebApi.InboxMessages
55
{
66
internal sealed class ExampleMessageHandler : IInboxMessageHandler<ExampleMessage>
77
{
8+
/*
89
private readonly SampleDbContext _context;
910
1011
public ExampleMessageHandler(SampleDbContext dbContext)
1112
{
1213
_context = dbContext;
1314
}
15+
*/
1416

1517
public async Task Handle(ExampleMessage message, IExecutionContext executionContext)
1618
{
1719
// Logic
1820
// TODO config AutoSaveChanges = false (default)
19-
await _context.SaveChangesAsync(executionContext.CancellationToken);
21+
//await _context.SaveChangesAsync(executionContext.CancellationToken);
2022
}
2123
}
2224
}

0 commit comments

Comments
 (0)