feat(messaging): add dynamic router pattern#368
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Test Results 1 files 1 suites 2m 8s ⏱️ Results for commit 5093753. |
🔍 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. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #368 +/- ##
==========================================
+ Coverage 89.65% 95.61% +5.96%
==========================================
Files 496 500 +4
Lines 40657 40963 +306
Branches 5859 5911 +52
==========================================
+ Hits 36449 39165 +2716
+ Misses 1912 1798 -114
+ Partials 2296 0 -2296
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:
|
Code Coverage |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new Dynamic Router messaging pattern to PatternKit, including a runtime-mutable DynamicRouter<TPayload, TResult> API and a companion [GenerateDynamicRouter] source generator, plus end-to-end examples, docs, and benchmark coverage to keep the production-readiness catalog consistent.
Changes:
- Added
DynamicRouter<TPayload, TResult>(fluent builder + runtime register/unregister) and TinyBDD coverage. - Added
DynamicRouterGenerator+ new generator attributes and Roslyn-based generator tests/diagnostics coverage. - Added a DI-importable order fulfillment example, documentation entries, pattern catalog updates, and BenchmarkDotNet scenario/results matrix updates.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/PatternKit.Tests/Messaging/Routing/DynamicRouterTests.cs | New unit tests for fluent + runtime mutation behavior and argument validation. |
| test/PatternKit.Generators.Tests/DynamicRouterGeneratorTests.cs | New Roslyn generator tests covering generation and diagnostics. |
| test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs | Updates catalog assertions to include Dynamic Router. |
| test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitBenchmarkCoverageTests.cs | Updates benchmark matrix expectations for new pattern count/results. |
| test/PatternKit.Examples.Tests/Messaging/OrderDynamicRouterExampleTests.cs | Adds example validation for fluent vs generated parity and DI wiring. |
| src/PatternKit.Generators/Messaging/DynamicRouterGenerator.cs | New incremental generator implementation for dynamic router factories + diagnostics. |
| src/PatternKit.Generators.Abstractions/Messaging/DynamicRouterAttributes.cs | New public attributes for dynamic router generation. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs | Registers Dynamic Router in the production-readiness pattern catalog. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs | Adds “Order Dynamic Router” example descriptor. |
| src/PatternKit.Examples/Messaging/OrderDynamicRouterExample.cs | Adds runtime + generated example, runner, and DI extension. |
| src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs | Wires the new example into the aggregate examples registration surface. |
| src/PatternKit.Core/Messaging/Routing/DynamicRouter.cs | New runtime-mutable router implementation. |
| README.md | Updates pattern counts and benchmark matrix entries. |
| docs/patterns/toc.yml | Adds Dynamic Router to pattern docs TOC. |
| docs/patterns/messaging/dynamic-router.md | New Dynamic Router pattern documentation page. |
| docs/guides/pattern-coverage.md | Adds Dynamic Router to the coverage guide table. |
| docs/guides/benchmarks.md | Adds Dynamic Router benchmark rows to published guidance. |
| docs/guides/benchmark-results.md | Updates published benchmark results + coverage matrix for new pattern/generator. |
| docs/generators/toc.yml | Adds Dynamic Router generator to generator docs TOC. |
| docs/generators/dynamic-router.md | New Dynamic Router generator documentation page. |
| docs/examples/toc.yml | Adds Order Dynamic Router to examples TOC. |
| docs/examples/order-dynamic-router.md | New Order Dynamic Router example documentation page. |
| benchmarks/PatternKit.Benchmarks/Messaging/DynamicRouterBenchmarks.cs | Adds a Dynamic Router BenchmarkDotNet scenario (fluent vs generated). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var entry = new RouteEntry(name, order, predicate, handler); | ||
| lock (_gate) | ||
| { | ||
| _routes = _routes | ||
| .Where(route => !string.Equals(route.Name, name, StringComparison.Ordinal)) | ||
| .Append(entry) | ||
| .OrderBy(static route => route.Order) | ||
| .ThenBy(static route => route.Name, StringComparer.Ordinal) | ||
| .ToArray(); | ||
| } |
| /// <summary>Routes <paramref name="message"/> through the current route snapshot.</summary> | ||
| public TResult Route(Message<TPayload> message, MessageContext? context = null) | ||
| { | ||
| if (message is null) | ||
| throw new ArgumentNullException(nameof(message)); | ||
|
|
||
| var effectiveContext = context ?? MessageContext.From(message); | ||
| var snapshot = _routes; | ||
| foreach (var route in snapshot) | ||
| if (route.Predicate(message, effectiveContext)) | ||
| return route.Handler(message, effectiveContext); |
|
|
||
| foreach (var route in routes) | ||
| sb.Append(" .When(@\"").Append(route.Name).Append("\", ").Append(route.Order).Append(", ").Append(route.PredicateMethodName).Append(").Then(").Append(route.HandlerMethodName).AppendLine(")"); | ||
|
|
||
| if (defaultHandler is not null) | ||
| sb.Append(" .Default(").Append(defaultHandler).AppendLine(")"); | ||
|
|
Summary
Validation