feat: add Gateway Routing pattern#319
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Test Results 1 files 1 suites 2m 37s ⏱️ Results for commit 1a45c41. ♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Pull request overview
Adds a new Gateway Routing pattern to PatternKit, including a fluent runtime router, a Roslyn incremental generator to emit router factories from attributes, and a documented/DI-importable example with catalog coverage.
Changes:
- Introduces
GatewayRouting<TRequest,TResponse>runtime with ordered route dispatch and fallback handling. - Adds
[GenerateGatewayRouting]+ route/handler/fallback attributes and aGatewayRoutingGeneratorwith diagnosticsPKGR001–PKGR005. - Adds tests, example integration (DI + ASP.NET Core minimal API mapping), and updates docs/catalog entries.
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/Cloud/GatewayRouting/GatewayRoutingTests.cs | Adds runtime behavior + validation coverage for dispatch/fallback/config errors. |
| test/PatternKit.Generators.Tests/GatewayRoutingGeneratorTests.cs | Verifies generated factory output + diagnostics emission. |
| test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs | Ensures new generator attributes are covered by attribute surface tests. |
| test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs | Updates production readiness catalog expectations for new pattern. |
| test/PatternKit.Examples.Tests/GatewayRoutingDemo/ProductGatewayRoutingDemoTests.cs | Tests fluent + generated example behavior and catalog registration. |
| src/PatternKit.Generators/GatewayRouting/GatewayRoutingGenerator.cs | Implements new incremental generator and diagnostics. |
| src/PatternKit.Generators/AnalyzerReleases.Unshipped.md | Registers new diagnostic IDs PKGR001–PKGR005. |
| src/PatternKit.Generators.Abstractions/Cloud/GatewayRoutingAttributes.cs | Adds generator attribute types for Gateway Routing. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs | Catalogs the pattern’s runtime/generator/docs/example/test artifacts. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs | Adds the “Product Gateway Routing” example descriptor. |
| src/PatternKit.Examples/GatewayRoutingDemo/ProductGatewayRoutingDemo.cs | Adds example: fluent router, generated router, DI extension, endpoint mapping. |
| src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs | Adds DI import surface for the new example. |
| src/PatternKit.Core/Cloud/GatewayRouting/GatewayRouting.cs | Adds Gateway Routing runtime implementation. |
| docs/patterns/toc.yml | Adds Gateway Routing to patterns TOC. |
| docs/patterns/cloud/gateway-routing.md | Documents the new pattern and runtime usage. |
| docs/guides/pattern-coverage.md | Adds pattern coverage entry for Gateway Routing. |
| docs/generators/toc.yml | Adds Gateway Routing to generator docs TOC. |
| docs/generators/index.md | Adds generator index entry + quick reference snippet. |
| docs/generators/gateway-routing.md | Documents generator usage + diagnostics list. |
| docs/examples/toc.yml | Adds the Product Gateway Routing example to examples TOC. |
| docs/examples/product-gateway-routing.md | Documents the example usage and integration surfaces. |
| docs/examples/index.md | Adds the example to the examples index listing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private static NamedMember[] NamedMembers(INamedTypeSymbol type, string attributeName) | ||
| => type.GetMembers().OfType<IMethodSymbol>() | ||
| .Select(method => new | ||
| { | ||
| Method = method, | ||
| Attribute = method.GetAttributes().FirstOrDefault(attr => attr.AttributeClass?.ToDisplayString() == attributeName) | ||
| }) | ||
| .Where(static item => item.Attribute is not null) | ||
| .Select(item => new NamedMember((string)item.Attribute!.ConstructorArguments[0].Value!, item.Method, attributeName == RouteAttributeName ? MemberKind.Route : MemberKind.Handler)) | ||
| .ToArray(); |
| private static FallbackMember[] MembersWith(INamedTypeSymbol type, string attributeName) | ||
| => type.GetMembers().OfType<IMethodSymbol>() | ||
| .Select(method => new | ||
| { | ||
| Method = method, | ||
| Attribute = method.GetAttributes().FirstOrDefault(attr => attr.AttributeClass?.ToDisplayString() == attributeName) | ||
| }) | ||
| .Where(static item => item.Attribute is not null) | ||
| .Select(static item => new FallbackMember(item.Attribute!.ConstructorArguments.Length == 0 ? "fallback" : (string)item.Attribute.ConstructorArguments[0].Value!, item.Method)) | ||
| .ToArray(); |
| private static readonly DiagnosticDescriptor DuplicateRoute = new( | ||
| "PKGR004", "Gateway Routing route is duplicated", | ||
| "Gateway Routing route name '{0}' is duplicated", | ||
| "PatternKit.Generators.GatewayRouting", DiagnosticSeverity.Error, true); | ||
|
|
||
| private static readonly DiagnosticDescriptor MissingHandler = new( | ||
| "PKGR005", "Gateway Routing handler is missing", | ||
| "Gateway Routing route '{0}' must have exactly one matching handler", | ||
| "PatternKit.Generators.GatewayRouting", DiagnosticSeverity.Error, true); |
| var pairs = routes.Select(route => new RoutePair(route.Name, route.Method, handlers.SingleOrDefault(handler => string.Equals(handler.Name, route.Name, StringComparison.OrdinalIgnoreCase))?.Method)).ToArray(); | ||
| var missing = pairs.FirstOrDefault(pair => pair.Handler is null); | ||
| if (missing is not null) | ||
| { | ||
| context.ReportDiagnostic(Diagnostic.Create(MissingHandler, node.Identifier.GetLocation(), missing.Name)); | ||
| return; |
🔍 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 #319 +/- ##
==========================================
+ Coverage 90.00% 95.86% +5.86%
==========================================
Files 452 456 +4
Lines 37512 37785 +273
Branches 5330 5377 +47
==========================================
+ Hits 33761 36223 +2462
+ Misses 1663 1562 -101
+ Partials 2088 0 -2088
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:
|
225c236 to
1a45c41
Compare
Code Coverage |
Summary
Closes #315
Validation
GatewayRoutingGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=falseGatewayRoutingGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=falseGatewayRoutingGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=falseNote: local full examples build remains blocked by the known CS9057 analyzer/compiler mismatch; hosted CI is authoritative for the full examples/docs pass.