Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/examples/production-ready-integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ using PatternKit.Examples.ProductionReadiness;

var services = new ServiceCollection()
.AddLogging()
.AddPatternKitExampleCatalog();
.AddPatternKitExampleCatalog()
.AddPatternKitPatternCatalog();

using var provider = services.BuildServiceProvider(validateScopes: true);
var catalog = provider.GetRequiredService<IPatternKitExampleCatalog>();
var patterns = provider.GetRequiredService<IPatternKitPatternCatalog>();
```

## Register runnable examples
Expand All @@ -25,6 +27,7 @@ The examples package also exposes a fluent IoC surface for every catalog entry.
```csharp
using Microsoft.Extensions.DependencyInjection;
using PatternKit.Examples.DependencyInjection;
using PatternKit.Examples.ProductionReadiness;

var services = new ServiceCollection()
.AddLogging()
Expand All @@ -34,6 +37,7 @@ using var provider = services.BuildServiceProvider(validateScopes: true);

var pricing = provider.GetRequiredService<PricingCalculatorExample>();
var catalog = provider.GetRequiredService<IPatternKitExampleCatalog>();
var patterns = provider.GetRequiredService<IPatternKitPatternCatalog>();
```

Each example also has its own focused extension, so sample applications can import only the slice they need:
Expand All @@ -59,6 +63,8 @@ Each `PatternKitExampleDescriptor` includes:
| `Patterns` | PatternKit primitives demonstrated by the example. |
| `ProductionChecks` | The behaviors that make the example production-shaped and regression-testable. |

The companion `IPatternKitPatternCatalog` records the canonical GoF pattern matrix. It links each pattern to its fluent runtime path, TinyBDD tests, real-world example, and source-generated path. Any missing generated path must point to a tracked issue; currently that is limited to the dedicated Interpreter generator and the dedicated Abstract Factory family generator.

## Validate in a generic host

Applications can fail fast during startup when catalog metadata is malformed or when source/docs/tests are missing from a repository checkout:
Expand Down
51 changes: 51 additions & 0 deletions docs/guides/pattern-coverage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Pattern Coverage

PatternKit tracks the canonical Gang of Four patterns as production surfaces, not just API names. Each pattern should have:

- a fluent runtime path in `PatternKit.Core`
- TinyBDD coverage for the runtime path
- user documentation and real-world examples
- an importable example path through `Microsoft.Extensions.DependencyInjection` where the example assembly is used
- a source-generated path, or a tracked issue when the generator is still planned

The source of truth is `PatternKitPatternCatalog` in `src/PatternKit.Examples/ProductionReadiness`. The TinyBDD tests in `PatternKitPatternCatalogTests` validate the catalog against the repository so missing files, missing examples, or undocumented generator gaps fail in CI.

## Current GoF Coverage

| Family | Pattern | Fluent path | Source-generated path |
| --- | --- | --- | --- |
| Creational | Abstract Factory | `AbstractFactory<,>` | Tracked in [#207](https://github.com/JerrettDavis/PatternKit/issues/207) |
| Creational | Builder | Builder helpers | Builder generator |
| Creational | Factory Method | `Factory<TKey, TValue>` | Factory Method generator |
| Creational | Prototype | `Prototype<TKey, TValue>` | Prototype generator |
| Creational | Singleton | `Singleton<T>` | Singleton generator |
| Structural | Adapter | `Adapter<TIn, TOut>` | Adapter generator |
| Structural | Bridge | `Bridge<TAbstraction, TImplementation>` | Bridge generator |
| Structural | Composite | `Composite<TNode, TResult>` | Composite generator |
| Structural | Decorator | `Decorator<TIn, TOut>` | Decorator generator |
| Structural | Facade | `Facade<TIn, TOut>` and `TypedFacade<T>` | Facade generator |
| Structural | Flyweight | `Flyweight<TKey, TValue>` | Flyweight generator |
| Structural | Proxy | `Proxy<TIn, TOut>` | Proxy generator |
| Behavioral | Chain of Responsibility | `ActionChain<T>` and `ResultChain<T>` | Chain generator |
| Behavioral | Command | `Command<T>` | Command generator |
| Behavioral | Interpreter | `Interpreter<TContext, TResult>` | Tracked in [#206](https://github.com/JerrettDavis/PatternKit/issues/206) |
| Behavioral | Iterator | `Flow<T>` and sequence helpers | Iterator generator |
| Behavioral | Mediator | `Mediator` | Dispatcher generator |
| Behavioral | Memento | `Memento<T>` | Memento generator |
| Behavioral | Observer | Observer primitives | Observer generator |
| Behavioral | State | `StateMachine<TState, TEvent>` | State Machine generator |
| Behavioral | Strategy | `Strategy<TIn, TOut>` and variants | Strategy generator |
| Behavioral | Template Method | `TemplateMethod<T>` and fluent templates | Template Method generator |
| Behavioral | Visitor | `Visitor<TBase, TResult>` and variants | Visitor generator |

## Adding Or Extending A Pattern

1. Add or update the fluent runtime implementation and TinyBDD tests.
2. Add or update the source generator, generator attributes, diagnostics, and TinyBDD generator tests.
3. Add a real-world example that can be imported from a normal application.
4. Register the example in `AddPatternKitExamples`.
5. Update the examples catalog and the pattern coverage catalog.
6. Add docs for the runtime path, generated path, and production example.
7. Run the relevant tests and land only when CI, docs, CodeQL, and coverage are green.

If a generator is intentionally deferred, create a GitHub issue and list the issue URL in the catalog. The tests allow only explicit, reviewed gaps.
2 changes: 2 additions & 0 deletions docs/guides/toc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
- name: Choosing Patterns
href: choosing-patterns.md
- name: Pattern Coverage
href: pattern-coverage.md
- name: Composing Patterns
href: composing-patterns.md
- name: Migrating from Traditional Patterns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public sealed class CoercerService<T> : ICoercer<T>
public T? From(object? value) => Coercer<T>.From(value);
}

public sealed record ProductionReadyExampleIntegrations(IPatternKitExampleCatalog Catalog);
public sealed record ProductionReadyExampleIntegrations(IPatternKitExampleCatalog ExampleCatalog, IPatternKitPatternCatalog PatternCatalog);
public sealed record AuthLoggingChainExample(ActionChain<HttpRequest> Chain, List<string> Log);
public sealed record CoercionExample(ICoercer<int> Integers, ICoercer<bool> Booleans, ICoercer<string> Strings);
public sealed record ComposedNotificationStrategyExample(AsyncStrategy<SendContext, SendResult> Strategy);
Expand Down Expand Up @@ -141,8 +141,11 @@ public static IServiceCollection AddPatternKitExamples(this IServiceCollection s
public static IServiceCollection AddProductionReadyExampleIntegrations(this IServiceCollection services)
{
services.AddPatternKitExampleCatalog();
services.AddPatternKitPatternCatalog();
services.AddSingleton<ProductionReadyExampleIntegrations>(sp =>
new(sp.GetRequiredService<IPatternKitExampleCatalog>()));
new(
sp.GetRequiredService<IPatternKitExampleCatalog>(),
sp.GetRequiredService<IPatternKitPatternCatalog>()));
return services.RegisterExample<ProductionReadyExampleIntegrations>("Production-Ready Example Integrations", ExampleIntegrationSurface.DependencyInjection | ExampleIntegrationSurface.GenericHost | ExampleIntegrationSurface.AspNetCore);
}

Expand Down
Loading
Loading