Skip to content

Commit 6a95c14

Browse files
Initial commit
0 parents  commit 6a95c14

21 files changed

+776
-0
lines changed

.github/workflows/dotnet.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: .NET 8 CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- 'AsyncAwaitFanOut.Core/**/*.cs'
8+
- 'AsyncAwaitFanOut.Tests/**/*.cs'
9+
- 'AsyncAwaitFanOut.ConsoleApp/**/*.cs'
10+
- 'AsyncAwaitFanOut.Core/**/*.csproj'
11+
- 'AsyncAwaitFanOut.Tests/**/*.csproj'
12+
- 'AsyncAwaitFanOut.ConsoleApp/**/*.csproj'
13+
- '.github/workflows/dotnet.yml'
14+
pull_request:
15+
branches: [ main ]
16+
paths:
17+
- 'AsyncAwaitFanOut.Core/**/*.cs'
18+
- 'AsyncAwaitFanOut.Tests/**/*.cs'
19+
- 'AsyncAwaitFanOut.ConsoleApp/**/*.cs'
20+
- 'AsyncAwaitFanOut.Core/**/*.csproj'
21+
- 'AsyncAwaitFanOut.Tests/**/*.csproj'
22+
- 'AsyncAwaitFanOut.ConsoleApp/**/*.csproj'
23+
- '.github/workflows/dotnet.yml'
24+
25+
jobs:
26+
build:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- name: Checkout code
30+
uses: actions/checkout@v4
31+
32+
- name: Setup .NET
33+
uses: actions/setup-dotnet@v4
34+
with:
35+
dotnet-version: 8.0.x
36+
37+
- name: Restore dependencies
38+
run: dotnet restore AsyncAwaitFanOut.sln
39+
40+
- name: Build
41+
run: dotnet build AsyncAwaitFanOut.sln --no-restore --configuration Release
42+
43+
- name: Test
44+
run: dotnet test AsyncAwaitFanOut.sln --no-build --configuration Release --verbosity normal

.gitignore

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Build directories
2+
bin/
3+
obj/
4+
out/
5+
[Bb]uild/
6+
7+
# User-specific files
8+
*.user
9+
*.suo
10+
*.userosscache
11+
*.sln.docstates
12+
13+
# Visual Studio cache / generated files
14+
.vs/
15+
*.pidb
16+
*.log
17+
*.svclog
18+
*.scc
19+
20+
# Rider / JetBrains
21+
.idea/
22+
*.DotSettings.user
23+
24+
# Autogenerated files
25+
Generated_Code/
26+
27+
# Test results
28+
TestResult*/
29+
*.trx
30+
*.coverage
31+
*.coveragexml
32+
33+
# NuGet packages
34+
*.nupkg
35+
*.snupkg
36+
packages/
37+
.nuget/
38+
project.lock.json
39+
project.fragment.lock.json
40+
41+
# Backup & temporary files
42+
*.bak
43+
*.tmp
44+
*.temp
45+
~$*
46+
47+
# Publish outputs
48+
publish/
49+
*.Publish.xml
50+
*.pubxml
51+
*.pubxml.user
52+
53+
# Env files / secrets
54+
.env
55+
.env.*
56+
57+
# OS junk files
58+
Thumbs.db
59+
.DS_Store
60+
desktop.ini
61+
62+
# ReSharper
63+
_ReSharper*/
64+
*.[Rr]e[Ss]harper
65+
*.DotSettings
66+
67+
# Git merge / diff tools
68+
*.orig
69+
*.rej
70+
71+
# Tool-specific
72+
*.sqlite
73+
*.db
74+
*.mdf
75+
*.ldf
76+
77+
# Local launch settings (if using Swagger or profiles)
78+
launchSettings.json
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+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\AsyncAwaitFanOut.Core\AsyncAwaitFanOut.Core.csproj" />
12+
</ItemGroup>
13+
14+
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using AsyncAwaitFanOut.Core.Services;
2+
3+
namespace AsyncAwaitFanOut.ConsoleApp
4+
{
5+
public class Program
6+
{
7+
public static async Task Main(string[] args)
8+
{
9+
// Demo wiring (no DI container needed for a console sample)
10+
var orderService = new OrderService();
11+
var paymentService = new PaymentService();
12+
var shippingService = new ShippingService();
13+
14+
var orderIds = Enumerable.Range(1, 8).Select(_ => Guid.NewGuid()).ToList();
15+
using var cts = new CancellationTokenSource();
16+
17+
var snapshotService = new OrderSnapshotService(
18+
orderService, paymentService, shippingService);
19+
20+
var snapshots = await snapshotService.GetOrderSnapshotsAsync(
21+
orderIds,
22+
maxConcurrency: 3,
23+
perCallTimeout: TimeSpan.FromMilliseconds(1500),
24+
cts.Token);
25+
26+
// Pretty print a tiny report
27+
Console.WriteLine("=== Order Snapshots ===");
28+
foreach (var s in snapshots)
29+
{
30+
var errs = (s.Errors?.Count ?? 0) == 0 ? "OK" : string.Join(" | ", s.Errors!);
31+
Console.WriteLine($"- {s.OrderId} :: " +
32+
$"Order? {(s.Order is null ? "no" : "yes")}, " +
33+
$"Payment? {(s.Payment is null ? "no" : "yes")}, " +
34+
$"Shipment? {(s.Shipment is null ? "no" : "yes")} :: " +
35+
$"{errs}");
36+
}
37+
38+
Console.WriteLine("\nDone.");
39+
}
40+
}
41+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
</Project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace AsyncAwaitFanOut.Core.DTOs
2+
{
3+
public class OrderDto
4+
{
5+
public Guid OrderId { get; set; }
6+
public string CustomerName { get; set; } = string.Empty;
7+
public DateTime Date { get; set; } = DateTime.UtcNow;
8+
public decimal Amount { get; set; }
9+
10+
public OrderDto() { }
11+
12+
public OrderDto(Guid orderId, string customerName, DateTime date, decimal amount)
13+
{
14+
OrderId = orderId;
15+
CustomerName = customerName;
16+
Date = date;
17+
Amount = amount;
18+
}
19+
}
20+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace AsyncAwaitFanOut.Core.DTOs
2+
{
3+
public class OrderSnapShot
4+
{
5+
public Guid OrderId { get; set; }
6+
public OrderDto? Order { get; set; }
7+
public PaymentDto? Payment { get; set; }
8+
public ShipmentDto? Shipment { get; set; }
9+
public List<string> Errors { get; set; } = new();
10+
11+
public OrderSnapShot() { }
12+
13+
public OrderSnapShot(
14+
Guid orderId,
15+
OrderDto? order,
16+
PaymentDto? payment,
17+
ShipmentDto? shipment,
18+
List<string>? errors)
19+
{
20+
OrderId = orderId;
21+
Order = order;
22+
Payment = payment;
23+
Shipment = shipment;
24+
Errors = errors ?? new List<string>();
25+
}
26+
}
27+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace AsyncAwaitFanOut.Core.DTOs
2+
{
3+
public class PaymentDto
4+
{
5+
public Guid OrderId { get; set; }
6+
public string Status { get; set; } = string.Empty;
7+
public DateTime AuthorizedAt { get; set; } = DateTime.UtcNow;
8+
9+
public PaymentDto() { }
10+
11+
public PaymentDto(Guid orderId, string status, DateTime authorizedAt)
12+
{
13+
OrderId = orderId;
14+
Status = status;
15+
AuthorizedAt = authorizedAt;
16+
}
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace AsyncAwaitFanOut.Core.DTOs
2+
{
3+
public class ShipmentDto
4+
{
5+
public Guid OrderId { get; set; }
6+
public string Carrier { get; set; } = string.Empty;
7+
public string Tracking { get; set; } = string.Empty;
8+
9+
public ShipmentDto() { }
10+
11+
public ShipmentDto(Guid orderId, string carrier, string tracking)
12+
{
13+
OrderId = orderId;
14+
Carrier = carrier;
15+
Tracking = tracking;
16+
}
17+
}
18+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using AsyncAwaitFanOut.Core.DTOs;
2+
3+
namespace AsyncAwaitFanOut.Core.Interfaces
4+
{
5+
public interface IOrderService
6+
{
7+
Task<OrderDto> GetOrderAsync(Guid orderId, CancellationToken ct);
8+
}
9+
}

0 commit comments

Comments
 (0)