Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,11 @@ var cachedRemoteProxy = Proxy<int, string>.Create(id => remoteProxy.Execute(id))
---

## Patterns Table
PatternKit currently tracks 120 production-readiness patterns. Each catalog pattern is represented in tests, documentation, real-world examples, IoC integration, and the BenchmarkDotNet coverage matrix.
PatternKit currently tracks 121 production-readiness patterns. Each catalog pattern is represented in tests, documentation, real-world examples, IoC integration, and the BenchmarkDotNet coverage matrix.

| Category | Count | Patterns |
| --- | ---: | --- |
| Application Architecture | 28 | Activity Tracker, Aggregate Root, Anti-Corruption Layer, Audit Log, Bounded Context, Context Map, CQRS, Data Mapper, Domain Event, Domain Service, Event Sourcing, Eventual Consistency Monitor, Feature Toggle, Identity Map, Lazy Load, Manual Task Gate, Materialized View, Ports and Adapters, Repository, Service Layer, Snapshot / Checkpoint Management, Specification, Table Data Gateway, Timeout Manager, Transaction Script, Unit of Work, Value Object, Workflow Orchestration |
| Application Architecture | 29 | Activity Tracker, Aggregate Root, Anti-Corruption Layer, Audit Log, Bounded Context, Context Map, CQRS, Data Mapper, Domain Event, Domain Service, Event Sourcing, Eventual Consistency Monitor, Feature Toggle, Identity Map, Lazy Load, Manual Task Gate, Materialized View, Ports and Adapters, Repository, Service Layer, Snapshot / Checkpoint Management, Specification, Table Data Gateway, Timeout Manager, Transaction Script, Unit of Work, Compensating Transaction, Value Object, Workflow Orchestration |
| Behavioral | 12 | Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Null Object, Observer, State, Strategy, Template Method, Visitor |
| Cloud Architecture | 21 | Ambassador, Backends for Frontends, Bulkhead, Cache-Aside, Cache Stampede Protection, Circuit Breaker, Distributed Lock / Lease, External Configuration Store, Gateway Aggregation, Gateway Routing, Health Endpoint Monitoring, Leader Election, Priority Queue, Queue-Based Load Leveling, Rate Limiting, Read-Through Cache, Retry, Scheduler Agent Supervisor, Sidecar, Strangler Fig, Write-Through Cache |
| Creational | 6 | Abstract Factory, Builder, Factory Method, Object Pool, Prototype, Singleton |
Expand Down Expand Up @@ -623,6 +623,8 @@ BenchmarkDotNet guidance is documented in [docs/guides/benchmarks.md](docs/guide
| Identity Map | Execution | 108.91 ns | 968 B | 94.83 ns | 968 B | Same allocation; generated was faster for scoped identity-map reuse. |
| Leader Election | Construction | 14.28 ns | 104 B | 15.91 ns | 104 B | Same allocation; fluent was slightly faster in this microbenchmark. |
| Leader Election | Execution | 43.62 ns | 360 B | 144.37 ns | 312 B | Generated allocated about 13% less memory, while fluent was faster in this path. |
| Compensating Transaction | Construction | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Compensating Transaction | Execution | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Distributed Lock / Lease | Construction | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Distributed Lock / Lease | Execution | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Materialized View | Construction | 140.9 ns | 1.05 KB | 147.4 ns | 1.05 KB | Same allocation; fluent was slightly faster in this microbenchmark. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using BenchmarkDotNet.Attributes;
using PatternKit.Application.CompensatingTransactions;
using PatternKit.Examples.CompensatingTransactionDemo;

namespace PatternKit.Benchmarks.Application;

[BenchmarkCategory("ApplicationArchitecture", "CompensatingTransaction")]
public class CompensatingTransactionBenchmarks
{
[Benchmark(Baseline = true, Description = "Fluent: create compensating transaction")]
[BenchmarkCategory("Fluent", "Construction")]
public CompensatingTransaction<CheckoutCompensatingTransactionContext> Fluent_CreateTransaction()
=> CheckoutCompensatingTransactionDemo.CreateFluent();

[Benchmark(Description = "Generated: create compensating transaction")]
[BenchmarkCategory("Generated", "Construction")]
public CompensatingTransaction<CheckoutCompensatingTransactionContext> Generated_CreateTransaction()
=> GeneratedCheckoutCompensatingTransaction.Create();

[Benchmark(Description = "Fluent: execute compensated checkout")]
[BenchmarkCategory("Fluent", "Execution")]
public ValueTask<CheckoutCompensatingTransactionSummary> Fluent_ExecuteCompensatedCheckout()
=> CheckoutCompensatingTransactionDemo.RunFluentAsync();

[Benchmark(Description = "Generated: execute compensated checkout")]
[BenchmarkCategory("Generated", "Execution")]
public ValueTask<CheckoutCompensatingTransactionSummary> Generated_ExecuteCompensatedCheckout()
=> CheckoutCompensatingTransactionDemo.RunGeneratedAsync();
}
10 changes: 10 additions & 0 deletions docs/examples/checkout-compensating-transaction-pattern.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Checkout Compensating Transaction Pattern

The checkout compensating transaction example models inventory reservation, payment authorization, and shipment creation. When shipment creation fails, the transaction voids payment and releases inventory in reverse order.

It demonstrates fluent and source-generated transaction construction, TinyBDD coverage, BenchmarkDotNet coverage, and `IServiceCollection` import through `AddCheckoutCompensatingTransactionDemo()`.

Files:

- `src/PatternKit.Examples/CompensatingTransactionDemo/CheckoutCompensatingTransactionDemo.cs`
- `test/PatternKit.Examples.Tests/CompensatingTransactionDemo/CheckoutCompensatingTransactionDemoTests.cs`
1 change: 1 addition & 0 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ dotnet test PatternKit.slnx -c Release
* **Inventory Ambassador:** `InventoryAmbassadorDemo` (+ `InventoryAmbassadorDemoTests`) — fluent and generated outbound connectivity wrapper with DI and ASP.NET Core mapping.
* **Warehouse Leader Election:** `WarehouseLeaderElectionDemo` (+ `WarehouseLeaderElectionDemoTests`) — fluent and generated active worker lease coordination with DI and Generic Host mapping.
* **Order Allocation Distributed Lock:** `OrderAllocationDistributedLockDemo` (+ `OrderAllocationDistributedLockDemoTests`) — fluent and generated resource lease coordination with DI and Generic Host mapping.
* **Checkout Compensating Transaction:** `CheckoutCompensatingTransactionDemo` (+ `CheckoutCompensatingTransactionDemoTests`) — fluent and generated reversible checkout steps with DI and Generic Host mapping.
* **Warehouse Scheduler Agent Supervisor:** `WarehouseSchedulerAgentSupervisorDemo` (+ `WarehouseSchedulerAgentSupervisorDemoTests`) — fluent and generated scheduled worker supervision with DI and Generic Host mapping.
* **Production-Ready Example Catalog:** `PatternKitExampleCatalog` (+ `PatternKitExampleCatalogTests`) — DI registration, generic host validation, ASP.NET Core endpoint mapping, and source/test/docs manifest checks.
* **Tests:** `PatternKit.Examples.Tests/*` use TinyBDD scenarios that read like specs.
Expand Down
3 changes: 3 additions & 0 deletions docs/examples/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@
- name: Order Allocation Distributed Lock
href: order-allocation-distributed-lock.md

- name: Checkout Compensating Transaction
href: checkout-compensating-transaction-pattern.md

- name: Warehouse Scheduler Agent Supervisor
href: warehouse-scheduler-agent-supervisor.md

Expand Down
24 changes: 24 additions & 0 deletions docs/generators/compensating-transaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Compensating Transaction Generator

`[GenerateCompensatingTransaction]` emits a `CompensatingTransaction<TContext>` factory from ordered step methods and named compensation methods.

```csharp
[GenerateCompensatingTransaction(TransactionName = "checkout")]
public static partial class CheckoutTransaction
{
[CompensatingTransactionStep("reserve-inventory", 10, Compensation = nameof(ReleaseInventory))]
private static ValueTask ReserveInventory(CheckoutContext context, CancellationToken ct) => default;

private static ValueTask ReleaseInventory(CheckoutContext context, CancellationToken ct) => default;
}
```

Diagnostics:

| ID | Meaning |
| --- | --- |
| `PKCOMP001` | Host type must be partial. |
| `PKCOMP002` | At least one `[CompensatingTransactionStep]` method is required. |
| `PKCOMP003` | Step, compensation, or condition method signature is invalid. |
| `PKCOMP004` | Step names and orders must be unique. |
| `PKCOMP005` | Factory method, transaction name, or compensation configuration is invalid. |
1 change: 1 addition & 0 deletions docs/generators/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ PatternKit includes a Roslyn incremental generator package (`PatternKit.Generato
| [**Timeout Manager**](timeout-manager.md) | Deadline registry for expiring pending workflow work | `[GenerateTimeoutManager]` |
| [**Audit Log**](audit-log.md) | Append-only audit log factories from key selectors | `[GenerateAuditLog]` |
| [**Unit of Work**](unit-of-work.md) | Ordered commit and rollback units | `[GenerateUnitOfWork]` |
| [**Compensating Transaction**](compensating-transaction.md) | Reversible business transactions from annotated step methods | `[GenerateCompensatingTransaction]` |
| [**Data Mapper**](data-mapper.md) | Domain/data model mapper factories | `[GenerateDataMapper]` |
| [**Identity Map**](identity-map.md) | Scoped object identity caches from key selectors | `[GenerateIdentityMap]` |
| [**Lazy Load**](lazy-load.md) | Deferred value factories with caching, TTL, and invalidation | `[GenerateLazyLoad]` |
Expand Down
3 changes: 3 additions & 0 deletions docs/generators/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@
- name: Unit of Work
href: unit-of-work.md

- name: Compensating Transaction
href: compensating-transaction.md

- name: Transaction Script
href: transaction-script.md

Expand Down
22 changes: 13 additions & 9 deletions docs/guides/benchmark-results.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ The latest measured timings below were captured on Windows 11, Intel Core i9-149
| Identity Map | Execution | 108.91 ns | 968 B | 94.83 ns | 968 B | Same allocation; generated was faster for scoped identity-map reuse. |
| Leader Election | Construction | 14.28 ns | 104 B | 15.91 ns | 104 B | Same allocation; fluent was slightly faster in this microbenchmark. |
| Leader Election | Execution | 43.62 ns | 360 B | 144.37 ns | 312 B | Generated allocated about 13% less memory, while fluent was faster in this path. |
| Compensating Transaction | Construction | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Compensating Transaction | Execution | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Distributed Lock / Lease | Construction | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Distributed Lock / Lease | Execution | Pending | Pending | Pending | Pending | Covered by the BenchmarkDotNet matrix; publish measured values after the next benchmark refresh. |
| Materialized View | Construction | 140.9 ns | 1.05 KB | 147.4 ns | 1.05 KB | Same allocation; fluent was slightly faster in this microbenchmark. |
Expand Down Expand Up @@ -262,19 +264,19 @@ The latest measured timings below were captured on Windows 11, Intel Core i9-149

## Coverage Matrix Summary

The coverage matrix currently publishes 120 catalog patterns and 480 pattern route results. Each pattern has four BenchmarkDotNet routes: fluent construction, fluent execution, source-generated construction, and source-generated execution. The reusable hosting integration matrix publishes 12 reusable hosting integration route results for package-level `IServiceCollection` registrations.
The coverage matrix currently publishes 121 catalog patterns and 484 pattern route results. Each pattern has four BenchmarkDotNet routes: fluent construction, fluent execution, source-generated construction, and source-generated execution. The reusable hosting integration matrix publishes 12 reusable hosting integration route results for package-level `IServiceCollection` registrations.

| Category | Patterns | Published route results |
| --- | ---: | ---: |
| Application Architecture | 28 | 112 |
| Application Architecture | 29 | 116 |
| Behavioral | 12 | 48 |
| Cloud Architecture | 21 | 84 |
| Creational | 6 | 24 |
| Enterprise Integration | 42 | 168 |
| Messaging Reliability | 4 | 16 |
| Structural | 7 | 28 |

The generator matrix currently publishes 115 generator source route results.
The generator matrix currently publishes 116 generator source route results.

## Hosting Integration Matrix Results

Expand Down Expand Up @@ -309,7 +311,8 @@ The generator matrix currently publishes 115 generator source route results.
| Application Architecture | Bounded Context | Covered | Covered | Covered | Covered |
| Application Architecture | Context Map | Covered | Covered | Covered | Covered |
| Application Architecture | CQRS | Covered | Covered | Covered | Covered |
| Application Architecture | Data Mapper | Covered | Covered | Covered | Covered |
| Application Architecture | Compensating Transaction | Covered | Covered | Covered | Covered |
| Application Architecture | Data Mapper | Covered | Covered | Covered | Covered |
| Application Architecture | Domain Event | Covered | Covered | Covered | Covered |
| Application Architecture | Domain Service | Covered | Covered | Covered | Covered |
| Application Architecture | Event Sourcing | Covered | Covered | Covered | Covered |
Expand Down Expand Up @@ -444,9 +447,10 @@ The generator matrix currently publishes 115 generator source route results.
| CanonicalDataModelGenerator | `src/PatternKit.Generators/CanonicalDataModel/CanonicalDataModelGenerator.cs` | Covered |
| ChainGenerator | `src/PatternKit.Generators/Chain/ChainGenerator.cs` | Covered |
| CircuitBreakerPolicyGenerator | `src/PatternKit.Generators/CircuitBreaker/CircuitBreakerPolicyGenerator.cs` | Covered |
| ExternalConfigurationStoreGenerator | `src/PatternKit.Generators/Cloud/ExternalConfigurationStoreGenerator.cs` | Covered |
| CommandGenerator | `src/PatternKit.Generators/Command/CommandGenerator.cs` | Covered |
| ComposerGenerator | `src/PatternKit.Generators/ComposerGenerator.cs` | Covered |
| ExternalConfigurationStoreGenerator | `src/PatternKit.Generators/Cloud/ExternalConfigurationStoreGenerator.cs` | Covered |
| CommandGenerator | `src/PatternKit.Generators/Command/CommandGenerator.cs` | Covered |
| CompensatingTransactionGenerator | `src/PatternKit.Generators/CompensatingTransactions/CompensatingTransactionGenerator.cs` | Covered |
| ComposerGenerator | `src/PatternKit.Generators/ComposerGenerator.cs` | Covered |
| CompositeGenerator | `src/PatternKit.Generators/Composite/CompositeGenerator.cs` | Covered |
| DataMapperGenerator | `src/PatternKit.Generators/DataMapping/DataMapperGenerator.cs` | Covered |
| DecoratorGenerator | `src/PatternKit.Generators/DecoratorGenerator.cs` | Covered |
Expand Down Expand Up @@ -556,5 +560,5 @@ dotnet run -c Release --framework net10.0 --project benchmarks/PatternKit.Benchm
Run only the matrix routes when validating benchmark coverage changes:

```powershell
dotnet run -c Release --framework net10.0 --project benchmarks/PatternKit.Benchmarks -- --filter *Matrix* --artifacts artifacts/benchmarks --join --job short
```
dotnet run -c Release --framework net10.0 --project benchmarks/PatternKit.Benchmarks -- --filter *Matrix* --artifacts artifacts/benchmarks --join --job short
```
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ if (parser.Execute("123", out var value))

## 📚 Available Patterns

PatternKit covers 120 production-readiness patterns with fluent APIs, source-generated routes where applicable, IoC integration examples, TinyBDD coverage, and BenchmarkDotNet coverage-matrix validation:
PatternKit covers 121 production-readiness patterns with fluent APIs, source-generated routes where applicable, IoC integration examples, TinyBDD coverage, and BenchmarkDotNet coverage-matrix validation:

| Category | Count | Patterns |
| --- | ---: | --- |
| Application Architecture | 28 | Activity Tracker, Aggregate Root, Anti-Corruption Layer, Audit Log, Bounded Context, Context Map, CQRS, Data Mapper, Domain Event, Domain Service, Event Sourcing, Eventual Consistency Monitor, Feature Toggle, Identity Map, Lazy Load, Manual Task Gate, Materialized View, Ports and Adapters, Repository, Service Layer, Snapshot / Checkpoint Management, Specification, Table Data Gateway, Timeout Manager, Transaction Script, Unit of Work, Value Object, Workflow Orchestration |
| Application Architecture | 29 | Activity Tracker, Aggregate Root, Anti-Corruption Layer, Audit Log, Bounded Context, Context Map, CQRS, Data Mapper, Domain Event, Domain Service, Event Sourcing, Eventual Consistency Monitor, Feature Toggle, Identity Map, Lazy Load, Manual Task Gate, Materialized View, Ports and Adapters, Repository, Service Layer, Snapshot / Checkpoint Management, Specification, Table Data Gateway, Timeout Manager, Transaction Script, Unit of Work, Compensating Transaction, Value Object, Workflow Orchestration |
| Behavioral | 12 | Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Null Object, Observer, State, Strategy, Template Method, Visitor |
| Cloud Architecture | 21 | Ambassador, Backends for Frontends, Bulkhead, Cache-Aside, Cache Stampede Protection, Circuit Breaker, Distributed Lock / Lease, External Configuration Store, Gateway Aggregation, Gateway Routing, Health Endpoint Monitoring, Leader Election, Priority Queue, Queue-Based Load Leveling, Rate Limiting, Read-Through Cache, Retry, Scheduler Agent Supervisor, Sidecar, Strangler Fig, Write-Through Cache |
| Creational | 6 | Abstract Factory, Builder, Factory Method, Object Pool, Prototype, Singleton |
Expand Down
17 changes: 17 additions & 0 deletions docs/patterns/application/compensating-transaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Compensating Transaction

Compensating Transaction records a sequence of reversible business steps. PatternKit's `CompensatingTransaction<TContext>` executes each step in order and, when a later step fails, runs completed compensation actions in reverse order.

```csharp
var transaction = CompensatingTransaction<CheckoutContext>
.Create("checkout")
.AddStep("reserve-inventory", ReserveAsync, ReleaseAsync, step => step.At(10))
.AddStep("authorize-payment", AuthorizeAsync, VoidAsync, step => step.At(20))
.Build();

var execution = await transaction.ExecuteAsync(context, ct);
```

Use it for workflows that cross boundaries where a database transaction is unavailable: inventory reservations, payment authorization, shipment creation, tenant provisioning, and external API side effects.

See [Compensating Transaction Generator](../../generators/compensating-transaction.md).
2 changes: 2 additions & 0 deletions docs/patterns/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@
href: application/repository.md
- name: Unit of Work
href: application/unit-of-work.md
- name: Compensating Transaction
href: application/compensating-transaction.md
- name: Data Mapper
href: application/data-mapper.md
- name: Identity Map
Expand Down
Loading
Loading