feat: add Unit of Work pattern#250
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Test Results 1 files 1 suites 2m 32s ⏱️ Results for commit f559aba. ♻️ This comment has been updated with latest results. |
🔍 PR Validation ResultsVersion: `` ✅ Validation Steps
📊 ArtifactsDry-run artifacts have been uploaded and will be available for 7 days. This comment was automatically generated by the PR validation workflow. |
There was a problem hiding this comment.
Pull request overview
Adds a first-class Unit of Work slice to PatternKit, including a fluent runtime API and a Roslyn incremental generator for attributed unit-of-work factories, plus docs, examples, DI integration, and test coverage to support the new pattern.
Changes:
- Introduces
PatternKit.Application.UnitOfWork.UnitOfWorkruntime with ordered commit and reverse-order rollback compensation. - Adds
[GenerateUnitOfWork]/[UnitOfWorkStep]attributes and aUnitOfWorkGeneratorwith diagnostics (PKUOW001–PKUOW004). - Adds checkout demo + DI wiring, catalog entries, and documentation pages, with new tests across core, generator, and examples.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| test/PatternKit.Tests/Application/UnitOfWork/UnitOfWorkTests.cs | Adds runtime behavior tests for ordered commit, rollback, and input/cancellation validation. |
| test/PatternKit.Generators.Tests/UnitOfWorkGeneratorTests.cs | Adds generator tests for factory emission and key diagnostics. |
| test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs | Extends attribute coverage to include unit-of-work attributes. |
| test/PatternKit.Examples.Tests/UnitOfWorkDemo/CheckoutUnitOfWorkDemoTests.cs | Adds example validation for fluent vs generated UoW and DI import. |
| test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs | Updates catalog expectations to include Unit of Work. |
| test/PatternKit.Examples.Tests/DependencyInjection/PatternKitExampleDependencyInjectionTests.cs | Verifies the new Unit of Work example is resolvable and runnable via DI. |
| src/PatternKit.Generators/UnitOfWork/UnitOfWorkGenerator.cs | Implements the incremental generator and diagnostics for attributed units of work. |
| src/PatternKit.Generators/AnalyzerReleases.Unshipped.md | Registers new PKUOW analyzer IDs. |
| src/PatternKit.Generators.Abstractions/UnitOfWork/UnitOfWorkAttributes.cs | Adds [GenerateUnitOfWork] and [UnitOfWorkStep] attributes. |
| src/PatternKit.Examples/UnitOfWorkDemo/CheckoutUnitOfWorkDemo.cs | Adds checkout Unit of Work demo (fluent + generated) and IServiceCollection integration. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs | Adds Unit of Work to the pattern catalog with docs/tests/example references. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs | Adds example descriptor for “Checkout Unit of Work Pattern”. |
| src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs | Registers the new checkout unit-of-work example in the examples DI bundle. |
| src/PatternKit.Core/Application/UnitOfWork/UnitOfWork.cs | Introduces the core UnitOfWork runtime types and result models. |
| docs/patterns/toc.yml | Adds Unit of Work to patterns TOC. |
| docs/patterns/application/unit-of-work.md | Adds pattern documentation for the runtime API and links to generator docs. |
| docs/guides/pattern-coverage.md | Updates coverage matrix to include Unit of Work and its generator. |
| docs/generators/unit-of-work.md | Adds generator documentation and diagnostic ID table. |
| docs/generators/toc.yml | Adds Unit of Work to generators TOC. |
| docs/generators/index.md | Adds Unit of Work to the generator index table. |
| docs/examples/toc.yml | Adds checkout unit-of-work example to examples TOC. |
| docs/examples/checkout-unit-of-work-pattern.md | Adds example documentation page and file references. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private UnitOfWorkResult( | ||
| bool committed, | ||
| IReadOnlyList<string> committedSteps, | ||
| string? failedStep, | ||
| Exception? exception, | ||
| UnitOfWorkRollbackResult? rollback) | ||
| { | ||
| Committed = committed; | ||
| CommittedSteps = committedSteps; | ||
| FailedStep = failedStep; | ||
| Exception = exception; | ||
| Rollback = rollback; | ||
| } |
| public sealed class UnitOfWorkRollbackResult | ||
| { | ||
| public UnitOfWorkRollbackResult(IReadOnlyList<string> rolledBackSteps, IReadOnlyList<Exception> failures) | ||
| { | ||
| RolledBackSteps = rolledBackSteps; | ||
| Failures = failures; | ||
| } | ||
|
|
||
| public IReadOnlyList<string> RolledBackSteps { get; } | ||
| public IReadOnlyList<Exception> Failures { get; } | ||
| public bool Succeeded => Failures.Count == 0; |
| return methods.SelectMany(method => method.GetAttributes() | ||
| .Where(static attr => attr.AttributeClass?.ToDisplayString() == StepAttributeName) | ||
| .Select(attr => new StepConfig( | ||
| method, | ||
| attr.ConstructorArguments[0].Value?.ToString() ?? method.Name, | ||
| (int)(attr.ConstructorArguments[1].Value ?? 0), | ||
| GetNamedString(attr, "RollbackMethodName")))) | ||
| .Select(step => step with { Rollback = step.RollbackName is null ? null : methods.FirstOrDefault(m => m.Name == step.RollbackName) }) | ||
| .ToList(); |
| if (!IsStep(step.Commit) || (step.Rollback is not null && !IsStep(step.Rollback))) | ||
| { | ||
| context.ReportDiagnostic(Diagnostic.Create(InvalidStep, step.Commit.Locations.FirstOrDefault(), step.Commit.Name)); |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #250 +/- ##
==========================================
+ Coverage 90.92% 96.20% +5.28%
==========================================
Files 316 320 +4
Lines 29311 29577 +266
Branches 4087 4116 +29
==========================================
+ Hits 26650 28454 +1804
+ Misses 1181 1123 -58
+ Partials 1480 0 -1480
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
5055bfb to
f559aba
Compare
Code Coverage |
Summary
Closes #237.
Validation
Note: local examples build still hits the existing Roslyn analyzer/compiler mismatch (CS9057) and generated-type cascade; hosted CI validates the examples matrix.