Skip to content

Commit 6c4abec

Browse files
Merge pull request #3 from U2UTraining/ConvertToTUnit
Convert to TUnit
2 parents ccf8cbf + 1373fae commit 6c4abec

29 files changed

Lines changed: 563 additions & 185 deletions

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<PackageVersion Include="coverlet.collector" Version="8.0.0" />
6464
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />
6565
<PackageVersion Include="TUnit" Version="1.18.37" />
66+
<PackageVersion Include="Imposter" Version="0.1.9" />
6667
</ItemGroup>
6768
<ItemGroup>
6869
<!-- Test Containers -->

ModularMonolith.slnx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@
2626
<Project Path="src/ModularMonolith.Smtp4Dev.Hosting/ModularMonolith.Smtp4Dev.Hosting.csproj" />
2727
</Folder>
2828
<Folder Name="/tests/">
29-
<Project Path="tests/BoardGames.Tests/BoardGames.Tests.csproj" Id="83b35844-8523-45c5-a4f3-87b361732d87" />
30-
<Project Path="tests/EFCore.Tests/EFCore.Tests.csproj" Id="6dce8182-cf90-478a-8960-e1bf3e2e4d08">
31-
<Build Solution="Debug|*" Project="false" />
32-
</Project>
29+
<Project Path="tests/ModularMonolith.APIs.Tests/ModularMonolith.APIs.Tests.csproj" Id="ea3bb2c1-cd40-4502-a06b-821a9a702d3d" />
3330
<Project Path="tests/ModularMonolith.Architecture.Tests/ModularMonolith.Architecture.Tests.csproj" Id="e92113b3-4fe2-408f-b859-19c6988d9205" />
34-
<Project Path="tests/Common.Specifications.Tests/Common.Specifications.Tests.csproj" Id="3cfbaf2c-2114-44d7-9268-b643856eefa4" />
3531
</Folder>
3632
</Solution>

src/ModularMonolith.APIs/BoundedContexts/BoardGames/EndPoints/ApplyMegaDiscount.cs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
namespace ModularMonolith.APIs.BoundedContexts.BoardGames.EndPoints;
1+
using Microsoft.EntityFrameworkCore.Storage;
2+
3+
namespace ModularMonolith.APIs.BoundedContexts.BoardGames.EndPoints;
24

35
[Register(
46
lifetime: ServiceLifetime.Scoped
57
, methodNameHint: "AddBoardGameServices")]
68
public sealed class ApplyMegaDiscount(
79
BoardGamesDb db
8-
, IIntegrationEventPublisher integrationEventPublisher)
10+
, [FromKeyedServices(nameof(BoardGamesDb))] IOutboxSignal outboxSignal
11+
//, IIntegrationEventPublisher integrationEventPublisher
12+
)
913
{
1014
public async Task<Results<Ok, BadRequest>> ExecuteAsync(
1115
decimal factor
@@ -19,20 +23,41 @@ decimal factor
1923
//}
2024
//await SaveChangesAsync(cancellationToken);
2125

22-
// ✅ Use Set-based update (no materialization)
23-
await db.BoardGames.ExecuteUpdateAsync(s =>
24-
s.SetProperty(bg => bg.Price.Amount,
25-
bg => bg.Price.Amount * factor)
26-
, cancellationToken
27-
)
28-
.ConfigureAwait(false);
29-
// Now we need to update the entities that are in memory
30-
// We can do this using an Integration Event
31-
await integrationEventPublisher.PublishIntegrationEventAsync(
32-
new GamesHaveChangedIntegrationEvent(
33-
EventId: Guid.NewGuid()
34-
), cancellationToken
35-
).ConfigureAwait(false);
26+
IExecutionStrategy strategy = db.Database.CreateExecutionStrategy();
27+
28+
await strategy.ExecuteAsync(async () =>
29+
{
30+
using IDbContextTransaction tx = await db.Database
31+
.BeginTransactionAsync(cancellationToken)
32+
.ConfigureAwait(false);
33+
34+
try
35+
{
36+
// ✅ Use Set-based update (no materialization)
37+
await db.BoardGames.ExecuteUpdateAsync(s =>
38+
s.SetProperty(bg => bg.Price.Amount,
39+
bg => bg.Price.Amount * factor)
40+
, cancellationToken
41+
)
42+
.ConfigureAwait(false);
43+
44+
// Now we need to update the entities that are in memory
45+
// We can do this using an Integration Event
46+
GamesHaveChangedIntegrationEvent @event =
47+
new GamesHaveChangedIntegrationEvent(
48+
EventId: Guid.NewGuid()
49+
);
50+
await db.SaveChangesAsync(@event, outboxSignal, cancellationToken)
51+
.ConfigureAwait(false);
52+
53+
await tx.CommitAsync(cancellationToken);
54+
}
55+
catch
56+
{
57+
await tx.RollbackAsync(cancellationToken).ConfigureAwait(false);
58+
throw; // Re-throw to allow the execution strategy to retry
59+
}
60+
});
3661

3762
return TypedResults.Ok();
3863
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using ModularMonolith.APIs.BoundedContexts.BoardGames.IntegrationEvents;
2+
using ModularMonolith.APIs.BoundedContexts.Common.IntegrationEvents;
3+
4+
namespace ModularMonolith.BlazorApp.Components.BoardGames;
5+
6+
public class GamesHaveChangedIntegrationEventHandler(
7+
State _state
8+
, IToastService _toastService
9+
)
10+
: IIntegrationEventHandler<GamesHaveChangedIntegrationEvent>
11+
{
12+
public async ValueTask HandleAsync(
13+
GamesHaveChangedIntegrationEvent @event
14+
, CancellationToken cancellationToken)
15+
{
16+
if (_state.CurrentPage is BoardGamesPage boardGamesPage)
17+
{
18+
_toastService.ShowInfo(title: $"Prices have been updated");
19+
}
20+
await ValueTask.CompletedTask;
21+
}
22+
}

src/ModularMonolith.BlazorApp/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ private static async Task Main(string[] args)
4141
builder.Services.AddScoped<U2UBlazorIntegrationEventProcessor>();
4242
builder.Services.AddScoped<IIntegrationEventHandler<CurrencyHasChangedIntegrationEvent>, ClientCurrencyHasChangedIntegrationEventHandler>();
4343
builder.Services.AddSingleton<IntegrationEventsMetrics>();
44-
builder.Services.AddScoped< IIntegrationEventHandler<BoardGameSelectedForShoppingBasketIntegrationEvent>, BoardGameSelectedForShoppingBasketIntegrationEventHandler>();
44+
builder.Services.AddScoped<IIntegrationEventHandler<BoardGameSelectedForShoppingBasketIntegrationEvent>, BoardGameSelectedForShoppingBasketIntegrationEventHandler>();
45+
builder.Services.AddScoped<IIntegrationEventHandler<GamesHaveChangedIntegrationEvent>, GamesHaveChangedIntegrationEventHandler>();
4546

4647
// API Services -- DO NOT FORGET TRAILING SLASH! --
4748
builder.Services.AddHttpClient<CurrencyClient>(client =>

0 commit comments

Comments
 (0)