Skip to content

feat: add Strangler Fig pattern#318

Merged
JerrettDavis merged 1 commit into
mainfrom
feature/strangler-fig-310
May 22, 2026
Merged

feat: add Strangler Fig pattern#318
JerrettDavis merged 1 commit into
mainfrom
feature/strangler-fig-310

Conversation

@JerrettDavis
Copy link
Copy Markdown
Owner

Summary

  • add Strangler Fig runtime with fluent legacy-to-modern migration routing
  • add source generator attributes/generator with diagnostics PKSF001-PKSF004
  • add checkout migration example with IServiceCollection and ASP.NET Core endpoint integration
  • document pattern, generator, example, and production readiness catalogs

Closes #310

Validation

  • dotnet build src\PatternKit.Core\PatternKit.Core.csproj -f netstandard2.0 /p:UseSharedCompilation=false
  • dotnet build src\PatternKit.Core\PatternKit.Core.csproj -f net8.0 /p:UseSharedCompilation=false
  • dotnet build src\PatternKit.Core\PatternKit.Core.csproj -f net9.0 /p:UseSharedCompilation=false
  • dotnet build src\PatternKit.Core\PatternKit.Core.csproj -f net10.0 /p:UseSharedCompilation=false
  • dotnet build src\PatternKit.Generators.Abstractions\PatternKit.Generators.Abstractions.csproj /p:UseSharedCompilation=false
  • dotnet build src\PatternKit.Generators\PatternKit.Generators.csproj /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Tests\PatternKit.Tests.csproj -f net8.0 --no-restore --filter "FullyQualifiedName~StranglerFigTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Tests\PatternKit.Tests.csproj -f net9.0 --no-restore --filter "FullyQualifiedName~StranglerFigTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Tests\PatternKit.Tests.csproj -f net10.0 --no-restore --filter "FullyQualifiedName~StranglerFigTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj -f net8.0 --no-restore --filter "FullyQualifiedNameStranglerFigGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj -f net9.0 --no-restore --filter "FullyQualifiedNameStranglerFigGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj -f net10.0 --no-restore --filter "FullyQualifiedNameStranglerFigGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • git diff --check

Note: local full examples build remains blocked by the known CS9057 analyzer/compiler mismatch; hosted CI is authoritative for the full examples/docs pass.

Copilot AI review requested due to automatic review settings May 22, 2026 13:31
@github-actions
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

@github-actions
Copy link
Copy Markdown
Contributor

Test Results

  1 files    1 suites   2m 27s ⏱️
959 tests 959 ✅ 0 💤 0 ❌
964 runs  964 ✅ 0 💤 0 ❌

Results for commit 19b3a25.

@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage

Summary
  Generated on: 05/22/2026 - 13:36:22
  Coverage date: 05/22/2026 - 13:35:16 - 05/22/2026 - 13:36:12
  Parser: MultiReport (9x Cobertura)
  Assemblies: 4
  Classes: 1335
  Files: 552
  Line coverage: 94.7%
  Covered lines: 36943
  Uncovered lines: 2029
  Coverable lines: 38972
  Total lines: 85850
  Branch coverage: 75.8% (10751 of 14177)
  Covered branches: 10751
  Total branches: 14177
  Method coverage: 96.3% (7210 of 7485)
  Full method coverage: 88.4% (6619 of 7485)
  Covered methods: 7210
  Fully covered methods: 6619
  Total methods: 7485

PatternKit.Core                                                                                                     95.9%
  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%
  PatternKit.Application.UnitOfWork.UnitOfWorkResult                                                                94.7%
  PatternKit.Application.UnitOfWork.UnitOfWorkRollbackResult                                                         100%
  PatternKit.Application.UnitOfWork.UnitOfWorkStep                                                                   100%
  PatternKit.Behavioral.Chain.ActionChain<T>                                                                         100%
  PatternKit.Behavioral.Chain.AsyncActionChain<T>                                                                    100%
  PatternKit.Behavioral.Chain.AsyncResultChain<T1, T2>                                                              97.7%
  PatternKit.Behavioral.Chain.ResultChain<T1, T2>                                                                    100%

@github-actions
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
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

❌ Patch coverage is 90.38462% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.88%. Comparing base (36faa71) to head (19b3a25).

Files with missing lines Patch % Lines
...t.Generators/StranglerFig/StranglerFigGenerator.cs 90.29% 13 Missing ⚠️
...mples/StranglerFigDemo/CheckoutStranglerFigDemo.cs 75.75% 8 Missing ⚠️
...PatternKit.Core/Cloud/StranglerFig/StranglerFig.cs 92.85% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #318      +/-   ##
==========================================
+ Coverage   90.07%   95.88%   +5.81%     
==========================================
  Files         448      452       +4     
  Lines       37254    37512     +258     
  Branches     5290     5330      +40     
==========================================
+ Hits        33555    35970    +2415     
+ Misses       1637     1542      -95     
+ Partials     2062        0    -2062     
Flag Coverage Δ
unittests 95.88% <90.38%> (+5.81%) ⬆️

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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Strangler Fig as a first-class PatternKit pattern, including a fluent runtime router, a Roslyn source generator + diagnostics (PKSF001–PKSF004), and an end-to-end checkout migration example that integrates with DI and ASP.NET Core minimal APIs. This expands the Cloud Architecture catalog with a new incremental legacy-to-modern migration capability.

Changes:

  • Introduces StranglerFig<TRequest,TResponse> runtime (decision/result model + fluent builder) for routing requests to legacy vs modern handlers.
  • Adds GenerateStranglerFig generator/attributes with diagnostics PKSF001–PKSF004 and generator/unit test coverage.
  • Adds a checkout migration example (fluent + generated), DI registration, endpoint mapping, and updates docs + production readiness catalogs.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/PatternKit.Tests/Cloud/StranglerFig/StranglerFigTests.cs Runtime behavior tests for modern vs legacy routing and configuration validation.
test/PatternKit.Generators.Tests/StranglerFigGeneratorTests.cs Generator tests for factory generation and PKSF diagnostics.
test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs Ensures Strangler Fig attributes are included in the abstractions coverage suite.
test/PatternKit.Examples.Tests/StranglerFigDemo/CheckoutStranglerFigDemoTests.cs Example tests covering fluent routing, DI import, and catalog assertions.
test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs Updates expected pattern list/counts to include Strangler Fig.
src/PatternKit.Generators/StranglerFig/StranglerFigGenerator.cs Incremental generator emitting Strangler Fig factory + diagnostics PKSF001–PKSF004.
src/PatternKit.Generators/AnalyzerReleases.Unshipped.md Registers new analyzer/generator diagnostic IDs (PKSF001–PKSF004).
src/PatternKit.Generators.Abstractions/Cloud/StranglerFigAttributes.cs Adds generator attributes: [GenerateStranglerFig], [StranglerFigRoute], [StranglerFigLegacy], [StranglerFigModern].
src/PatternKit.Examples/StranglerFigDemo/CheckoutStranglerFigDemo.cs Adds checkout Strangler Fig example with fluent + generated routes, DI extension, and endpoint mapping.
src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs Catalogs Strangler Fig pattern (docs/source/tests/generator/example paths + highlights).
src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs Adds “Checkout Strangler Fig Migration” example descriptor and integration surfaces.
src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs Adds DI-importable CheckoutStranglerFigExample and wires it into AddPatternKitExamples().
src/PatternKit.Core/Cloud/StranglerFig/StranglerFig.cs Implements the Strangler Fig runtime router, decisions, and results.
docs/patterns/toc.yml Adds Strangler Fig to the patterns TOC.
docs/patterns/cloud/strangler-fig.md Documents the Strangler Fig runtime usage and generator/DI entrypoints.
docs/guides/pattern-coverage.md Adds Strangler Fig to the pattern coverage guide table.
docs/generators/toc.yml Adds Strangler Fig generator doc to generators TOC.
docs/generators/strangler-fig.md Documents generator usage and diagnostics PKSF001–PKSF004.
docs/generators/index.md Adds Strangler Fig to the generator index + quick reference snippet.
docs/examples/toc.yml Adds checkout Strangler Fig example to examples TOC.
docs/examples/index.md Adds checkout Strangler Fig example to examples index list.
docs/examples/checkout-strangler-fig.md Documents the checkout Strangler Fig example usage (DI + runner).

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

Comment on lines +76 to +83
foreach (var route in _routes)
{
if (route.Matches(request))
return StranglerFigResult<TResponse>.From(Name, StranglerFigDecision.Modern(route.Name), _modern(request));
}

return StranglerFigResult<TResponse>.From(Name, StranglerFigDecision.Legacy(), _legacy(request));
}
{
ScenarioExpect.Empty(result.Diagnostics);
var source = ScenarioExpect.Single(result.GeneratedSources);
ScenarioExpect.Contains("Build()", source);
@JerrettDavis JerrettDavis merged commit 0483e40 into main May 22, 2026
13 checks passed
@JerrettDavis JerrettDavis deleted the feature/strangler-fig-310 branch May 22, 2026 13:42
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.

Add Strangler Fig migration pattern

2 participants