Skip to content

feat: add Ambassador pattern#325

Merged
JerrettDavis merged 1 commit into
mainfrom
feature/ambassador-320
May 22, 2026
Merged

feat: add Ambassador pattern#325
JerrettDavis merged 1 commit into
mainfrom
feature/ambassador-320

Conversation

@JerrettDavis
Copy link
Copy Markdown
Owner

Summary

  • add Ambassador runtime builder with transform, connection policy, telemetry, outbound call, and fallback behavior
  • add source generator and public attributes for generated ambassador factories
  • add inventory ambassador example with IServiceCollection and ASP.NET Core mapping
  • document the pattern/generator/example and wire production catalogs
  • add TinyBDD runtime, generator, attribute, catalog, and example coverage

Closes #320.

Validation

  • 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.Core\PatternKit.Core.csproj -f netstandard2.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~AmbassadorTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Tests\PatternKit.Tests.csproj -f net9.0 --no-restore --filter "FullyQualifiedName~AmbassadorTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Tests\PatternKit.Tests.csproj -f net10.0 --no-restore --filter "FullyQualifiedName~AmbassadorTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj -f net8.0 --no-restore --filter "FullyQualifiedNameAmbassadorGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj -f net9.0 --no-restore --filter "FullyQualifiedNameAmbassadorGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • dotnet test test\PatternKit.Generators.Tests\PatternKit.Generators.Tests.csproj -f net10.0 --no-restore --filter "FullyQualifiedNameAmbassadorGeneratorTests|FullyQualifiedNameAbstractionsAttributeCoverageTests" /p:BuildProjectReferences=false /p:UseSharedCompilation=false
  • git diff --check

Note: the local full examples build still hits the existing analyzer/compiler mismatch (CS9057 with generated demo types); hosted CI validates the full examples/docs surface.

Copilot AI review requested due to automatic review settings May 22, 2026 18:17
@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

787 tests   787 ✅  32s ⏱️
  1 suites    0 💤
  1 files      0 ❌

Results for commit 69d33fd.

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 a new Ambassador pattern to PatternKit, including a fluent runtime API for wrapping outbound calls, a Roslyn incremental generator for strongly-typed factory creation, and a production-shaped example wired into the Pattern/Example catalogs and docs.

Changes:

  • Introduces Ambassador<TRequest,TResponse> runtime with transforms, connection policy, telemetry steps, outbound call, and fallback handling.
  • Adds [GenerateAmbassador] + related member attributes and an AmbassadorGenerator with diagnostics and generator tests.
  • Adds an Inventory Ambassador example (DI + ASP.NET Core minimal API mapping), documentation, and catalog wiring/coverage updates.

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/Ambassador/AmbassadorTests.cs Adds runtime behavior coverage for transforms/telemetry/fallback/guard clauses.
test/PatternKit.Generators.Tests/AmbassadorGeneratorTests.cs Adds generator tests for emitted factory source and diagnostics.
test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs Extends attribute surface coverage to include Ambassador attributes.
test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs Updates catalog expectations to include Ambassador and adjusts family counts.
test/PatternKit.Examples.Tests/AmbassadorDemo/InventoryAmbassadorDemoTests.cs Adds example-level verification (fluent + generated + DI + catalogs).
src/PatternKit.Generators/AnalyzerReleases.Unshipped.md Registers new analyzer diagnostic IDs for the Ambassador generator.
src/PatternKit.Generators/Ambassador/AmbassadorGenerator.cs Implements the Ambassador incremental generator and diagnostics.
src/PatternKit.Generators.Abstractions/Cloud/AmbassadorAttributes.cs Adds public generator attributes for ambassador host + steps.
src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs Wires Ambassador pattern into the production pattern catalog.
src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs Adds the Inventory Ambassador entry to the production example catalog.
src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs Adds DI registration for the new example and aggregates it into AddPatternKitExamples().
src/PatternKit.Examples/AmbassadorDemo/InventoryAmbassadorDemo.cs Implements the Inventory Ambassador demo (runtime + generated + DI + endpoint mapping).
src/PatternKit.Core/Cloud/Ambassador/Ambassador.cs Adds the core Ambassador runtime types (Ambassador, context, result).
docs/patterns/toc.yml Adds Ambassador to the patterns TOC.
docs/patterns/cloud/ambassador.md Adds Ambassador pattern documentation and quick example.
docs/guides/pattern-coverage.md Adds Ambassador to the pattern coverage guide table.
docs/generators/toc.yml Adds Ambassador to the generators TOC.
docs/generators/index.md Adds Ambassador to the generator index table.
docs/generators/ambassador.md Adds generator documentation and diagnostic list.
docs/examples/toc.yml Adds Inventory Ambassador to examples TOC.
docs/examples/inventory-ambassador.md Adds Inventory Ambassador example documentation.
docs/examples/index.md Adds Inventory Ambassador to examples index summary list.

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

{
context.Request = transform(context.Request);
if (context.Request is null)
return AmbassadorResult<TResponse>.Failure(Name, new InvalidOperationException("Ambassador transform returned null."), context.Events.ToArray());
Comment on lines +24 to +32
private static readonly DiagnosticDescriptor MissingMembers = new(
"PKAMB002", "Ambassador members are missing",
"Ambassador type '{0}' must declare exactly one outbound call handler",
"PatternKit.Generators.Ambassador", DiagnosticSeverity.Error, true);

private static readonly DiagnosticDescriptor InvalidMember = new(
"PKAMB003", "Ambassador method signature is invalid",
"Ambassador method '{0}' has an invalid static signature for the configured request or response type",
"PatternKit.Generators.Ambassador", DiagnosticSeverity.Error, true);
Comment on lines +151 to +153
.Select(static item => new TelemetryMember((string)item.Attribute!.ConstructorArguments[0].Value!, item.Method))
.ToArray();

Diagnostics:

- `PKAMB001`: host type must be partial.
- `PKAMB002`: exactly one outbound call handler is required.
@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage

Summary
  Generated on: 05/22/2026 - 18:22:35
  Coverage date: 05/22/2026 - 18:21:27 - 05/22/2026 - 18:22:25
  Parser: MultiReport (9x Cobertura)
  Assemblies: 4
  Classes: 1400
  Files: 572
  Line coverage: 94.6%
  Covered lines: 38021
  Uncovered lines: 2142
  Coverable lines: 40163
  Total lines: 88108
  Branch coverage: 75.4% (11099 of 14707)
  Covered branches: 11099
  Total branches: 14707
  Method coverage: 96.2% (7476 of 7767)
  Full method coverage: 88.2% (6857 of 7767)
  Covered methods: 7476
  Fully covered methods: 6857
  Total methods: 7767

PatternKit.Core                                                                                                     95.8%
  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 89.93902% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.74%. Comparing base (0318b46) to head (69d33fd).

Files with missing lines Patch % Lines
...rnKit.Generators/Ambassador/AmbassadorGenerator.cs 89.57% 17 Missing ⚠️
src/PatternKit.Core/Cloud/Ambassador/Ambassador.cs 91.57% 8 Missing ⚠️
...Examples/AmbassadorDemo/InventoryAmbassadorDemo.cs 75.75% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #325      +/-   ##
==========================================
+ Coverage   89.83%   95.74%   +5.90%     
==========================================
  Files         464      468       +4     
  Lines       38355    38681     +326     
  Branches     5468     5524      +56     
==========================================
+ Hits        34458    37034    +2576     
+ Misses       1742     1647      -95     
+ Partials     2155        0    -2155     
Flag Coverage Δ
unittests 95.74% <89.93%> (+5.90%) ⬆️

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 merged commit 3eb565a into main May 22, 2026
13 checks passed
@JerrettDavis JerrettDavis deleted the feature/ambassador-320 branch May 22, 2026 18:28
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 Ambassador pattern

2 participants