Skip to content

feat: add aggregate root pattern slice#408

Merged
JerrettDavis merged 1 commit into
mainfrom
feat/domain-modeling-aggregate-root
May 28, 2026
Merged

feat: add aggregate root pattern slice#408
JerrettDavis merged 1 commit into
mainfrom
feat/domain-modeling-aggregate-root

Conversation

@JerrettDavis

Copy link
Copy Markdown
Owner

Adds the next domain-modeling slice for #403: Aggregate Root.

Includes:

  • runtime AggregateRoot<TId,TEvent> and AggregateCommandHandler<TAggregate,TCommand,TEvent> APIs
  • source generator attributes and AggregateCommandHandlerGenerator
  • TinyBDD coverage for runtime, generator, examples, and production-readiness catalogs
  • IServiceCollection-importable order aggregate root example
  • BenchmarkDotNet scenario and coverage matrix/docs updates
  • README/docs pattern tables and user guides

Local validation:

  • dotnet format PatternKit.slnx --verbosity minimal
  • dotnet build PatternKit.slnx --configuration Release --no-restore -m:1
  • dotnet test PatternKit.slnx --configuration Release --no-build -p:TestTfmsInParallel=false --logger "console;verbosity=minimal"
  • dotnet build benchmarks/PatternKit.Benchmarks/PatternKit.Benchmarks.csproj --configuration Release -m:1
  • docfx docs/docfx.json --warningsAsErrors

Copilot AI review requested due to automatic review settings May 28, 2026 18:24
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Domain Modeling “Aggregate Root” slice to PatternKit, spanning runtime APIs, a source generator, example/demo + DI integration, benchmark coverage, and production-readiness documentation/catalog updates (per #403).

Changes:

  • Introduces AggregateRoot<TId,TEvent> and AggregateCommandHandler<TAggregate,TCommand,TEvent> runtime APIs with TinyBDD coverage.
  • Adds aggregate command handler source generator + abstractions attributes, plus generator diagnostics/tests and analyzer release notes.
  • Adds an importable order Aggregate Root example, BenchmarkDotNet scenario, and updates pattern/benchmark catalogs + docs/README tables.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/PatternKit.Tests/Application/Aggregates/AggregateRootTests.cs New TinyBDD coverage for aggregate root versioning/uncommitted events + command handler behavior.
test/PatternKit.Generators.Tests/AggregateCommandHandlerGeneratorTests.cs Verifies generated factory output and validates diagnostics PKAGG001–PKAGG005.
test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs Adds coverage ensuring new aggregate attributes expose defaults and validate ctor args.
test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs Updates expected catalog pattern names/counts to include Aggregate Root.
test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitBenchmarkCoverageTests.cs Updates expected published route-result total to account for the new pattern.
test/PatternKit.Examples.Tests/AggregateRootDemo/OrderAggregateRootDemoTests.cs Ensures fluent vs generated parity and verifies DI import paths.
src/PatternKit.Generators/AnalyzerReleases.Unshipped.md Documents new generator diagnostics PKAGG001–PKAGG005.
src/PatternKit.Generators/Aggregates/AggregateCommandHandlerGenerator.cs New incremental generator emitting an aggregate command handler factory.
src/PatternKit.Generators.Abstractions/Aggregates/AggregateAttributes.cs Adds [GenerateAggregateCommandHandler], [AggregateDecision], [AggregateEventApplier].
src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs Registers “Aggregate Root” in the production pattern catalog with links to assets/tests/docs.
src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs Registers “Order Aggregate Root Pattern” in the example catalog.
src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs Adds DI wiring to import the new example via AddPatternKitExamples().
src/PatternKit.Examples/AggregateRootDemo/OrderAggregateRootDemo.cs Adds fluent + generated demo and an IServiceCollection extension + service wrapper.
src/PatternKit.Core/Application/Aggregates/AggregateRoot.cs Introduces the core runtime Aggregate Root + command handler/result APIs.
README.md Updates pattern counts/table and adds benchmark matrix rows for Aggregate Root.
docs/patterns/toc.yml Adds Aggregate Root to pattern TOC.
docs/patterns/application/aggregate-root.md New pattern documentation page for Aggregate Root (fluent + generated + IoC).
docs/index.md Updates pattern counts/table on docs landing page.
docs/guides/pattern-coverage.md Adds Aggregate Root row to the pattern coverage guide.
docs/guides/benchmarks.md Adds Aggregate Root rows to benchmark guidance table.
docs/guides/benchmark-results.md Updates counts and adds Aggregate Root to published benchmark results + generator matrix.
docs/generators/toc.yml Adds Aggregate Root generator to generators TOC.
docs/generators/aggregate-root.md New generator documentation page (usage, shapes, diagnostics).
docs/examples/toc.yml Adds “Order Aggregate Root Pattern” to examples TOC.
docs/examples/order-aggregate-root-pattern.md New example doc describing import/run/production notes.
benchmarks/PatternKit.Benchmarks/Application/AggregateRootBenchmarks.cs Adds dedicated BenchmarkDotNet scenario for fluent vs generated aggregate handler construction/execution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

private readonly List<TEvent> _uncommittedEvents = [];

protected AggregateRoot(TId id)
{
Comment on lines +31 to +48
protected void Raise(TEvent domainEvent, Action<TEvent> apply)
{
if (apply is null)
throw new ArgumentNullException(nameof(apply));

apply(domainEvent);
_uncommittedEvents.Add(domainEvent);
Version++;
}

protected void Replay(TEvent domainEvent, Action<TEvent> apply)
{
if (apply is null)
throw new ArgumentNullException(nameof(apply));

apply(domainEvent);
Version++;
}
Comment on lines +98 to +99
Handler = handler;
Events = events;
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Test Results

    12 files      12 suites   10m 15s ⏱️
 3 554 tests  3 554 ✅ 0 💤 0 ❌
10 673 runs  10 673 ✅ 0 💤 0 ❌

Results for commit e81fead.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Validation Results

Version: ``

✅ Validation Steps

  • Build solution
  • Run tests
  • Build documentation
  • Dry-run NuGet packaging

📊 Artifacts

Dry-run artifacts have been uploaded and will be available for 7 days.


This comment was automatically generated by the PR validation workflow.

@codecov

codecov Bot commented May 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.46154% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.67%. Comparing base (768e5fc) to head (e81fead).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ors/Aggregates/AggregateCommandHandlerGenerator.cs 97.72% 3 Missing ⚠️
...amples/AggregateRootDemo/OrderAggregateRootDemo.cs 97.72% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #408      +/-   ##
==========================================
+ Coverage   89.57%   95.67%   +6.09%     
==========================================
  Files         535      539       +4     
  Lines       43172    43432     +260     
  Branches     6230     6263      +33     
==========================================
+ Hits        38672    41552    +2880     
+ Misses       2029     1880     -149     
+ Partials     2471        0    -2471     
Flag Coverage Δ
unittests 95.67% <98.46%> (+6.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JerrettDavis JerrettDavis force-pushed the feat/domain-modeling-aggregate-root branch from d932ab2 to e81fead Compare May 28, 2026 18:38
@github-actions

Copy link
Copy Markdown
Contributor

Code Coverage

Summary
  Generated on: 05/28/2026 - 18:48:23
  Coverage date: 05/28/2026 - 18:44:15 - 05/28/2026 - 18:48:12
  Parser: MultiReport (12x Cobertura)
  Assemblies: 5
  Classes: 1636
  Files: 660
  Line coverage: 94.6%
  Covered lines: 42593
  Uncovered lines: 2403
  Coverable lines: 44996
  Total lines: 98182
  Branch coverage: 75.5% (12498 of 16540)
  Covered branches: 12498
  Total branches: 16540
  Method coverage: 96% (8538 of 8888)
  Full method coverage: 88.1% (7839 of 8888)
  Covered methods: 8538
  Fully covered methods: 7839
  Total methods: 8888

PatternKit.Core                                                                                                     95.4%
  PatternKit.Application.ActivityTracking.ActivityGateState                                                          100%
  PatternKit.Application.ActivityTracking.ActivityLease                                                              100%
  PatternKit.Application.ActivityTracking.ActivityRecord                                                             100%
  PatternKit.Application.ActivityTracking.ActivityTracker                                                            100%
  PatternKit.Application.Aggregates.AggregateCommandHandler<T1, T2, T3>                                              100%
  PatternKit.Application.Aggregates.AggregateCommandResult<T>                                                        100%
  PatternKit.Application.Aggregates.AggregateRoot<T1, T2>                                                            100%
  PatternKit.Application.AntiCorruption.AntiCorruptionLayer<T1, T2>                                                 90.4%
  PatternKit.Application.AntiCorruption.AntiCorruptionResult<T>                                                      100%
  PatternKit.Application.AuditLog.AuditLogAppendResult<T>                                                           85.7%
  PatternKit.Application.AuditLog.InMemoryAuditLog<T1, T2>                                                          95.4%
  PatternKit.Application.DataMapping.DataMapper<T1, T2>                                                             94.6%
  PatternKit.Application.DataMapping.DataMapperError                                                                  90%
  PatternKit.Application.DataMapping.DataMapperResult<T>                                                            84.6%
  PatternKit.Application.DomainEvents.DomainEventDispatcher<T>                                                      95.4%
  PatternKit.Application.DomainEvents.DomainEventDispatchResult                                                      100%
  PatternKit.Application.EventSourcing.EventStoreAppendResult                                                        100%
  PatternKit.Application.EventSourcing.InMemoryEventStore<T1, T2>                                                   97.9%
  PatternKit.Application.EventSourcing.StoredEvent<T1, T2>                                                            80%
  PatternKit.Application.FeatureToggles.FeatureToggleDecision                                                       87.5%
  PatternKit.Application.FeatureToggles.FeatureToggleRule<T>                                                         100%
  PatternKit.Application.FeatureToggles.FeatureToggleSet<T>                                                         96.9%
  PatternKit.Application.IdentityMap.IdentityMap<T1, T2>                                                             100%
  PatternKit.Application.IdentityMap.IdentityMapResult<T>                                                           92.8%
  PatternKit.Application.MaterializedViews.MaterializedView<T1, T2>                                                 98.4%
  PatternKit.Application.Repository.InMemoryRepository<T1, T2>                                                      92.8%
  PatternKit.Application.Repository.RepositoryResult<T>                                                             93.3%
  PatternKit.Application.ServiceLayer.ServiceLayerOperation<T1, T2>                                                 96.7%
  PatternKit.Application.ServiceLayer.ServiceLayerResult<T>                                                         94.7%
  PatternKit.Application.ServiceLayer.ServiceLayerRule<T>                                                            100%
  PatternKit.Application.Specification.Specification<T>                                                              100%
  PatternKit.Application.Specification.SpecificationRegistry<T>                                                     93.3%
  PatternKit.Application.TableDataGateway.InMemoryTableDataGateway<T1, T2>                                            86%
  PatternKit.Application.TableDataGateway.TableGatewayResult<T>                                                     82.3%
  PatternKit.Application.TransactionScript.TransactionScript<T1, T2>                                                  97%
  PatternKit.Application.TransactionScript.TransactionScriptError                                                     90%
  PatternKit.Application.TransactionScript.TransactionScriptResult<T>                                                100%
  PatternKit.Application.UnitOfWork.UnitOfWork                                                                      90.9%

@JerrettDavis JerrettDavis merged commit a1da42f into main May 28, 2026
12 checks passed
@JerrettDavis JerrettDavis deleted the feat/domain-modeling-aggregate-root branch May 28, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants