feat: add Repository pattern#249
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 d6b713b. |
Code Coverage |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #249 +/- ##
==========================================
+ Coverage 90.98% 96.24% +5.26%
==========================================
Files 312 316 +4
Lines 29089 29311 +222
Branches 4056 4087 +31
==========================================
+ Hits 26467 28211 +1744
+ Misses 1165 1100 -65
+ Partials 1457 0 -1457
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:
|
There was a problem hiding this comment.
Pull request overview
Adds a first-class Repository application-architecture slice to PatternKit, including an async-first runtime abstraction, an in-memory implementation, and a Roslyn source generator + docs/examples to integrate it into the existing pattern catalog.
Changes:
- Introduces
IRepository<TEntity,TKey>,InMemoryRepository<TEntity,TKey>, and mutation result types/status. - Adds
[GenerateRepository]+[RepositoryKeySelector]and an incremental generator that emits an in-memory repository factory with diagnostics. - Adds an order repository example with DI integration, plus tests and documentation/catalog updates.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test/PatternKit.Tests/Application/Repository/RepositoryTests.cs | Adds runtime repository behavior coverage (add/get/list/find/update/remove, validation, cancellation). |
| test/PatternKit.Generators.Tests/RepositoryGeneratorTests.cs | Adds generator tests for output and diagnostics PKREP001–PKREP003. |
| test/PatternKit.Generators.Tests/AbstractionsAttributeCoverageTests.cs | Extends attribute-coverage tests to include repository generator attributes. |
| test/PatternKit.Examples.Tests/RepositoryDemo/OrderRepositoryDemoTests.cs | Adds TinyBDD coverage for fluent + generated repository example and DI import. |
| test/PatternKit.Examples.Tests/ProductionReadiness/PatternKitPatternCatalogTests.cs | Updates catalog expectations to include the new Repository pattern. |
| test/PatternKit.Examples.Tests/DependencyInjection/PatternKitExampleDependencyInjectionTests.cs | Verifies the repository example resolves and runs via the aggregated examples DI registration. |
| src/PatternKit.Generators/Repository/RepositoryGenerator.cs | Implements the incremental generator and diagnostics for repository factories. |
| src/PatternKit.Generators/AnalyzerReleases.Unshipped.md | Registers new analyzer diagnostic IDs PKREP001–PKREP003. |
| src/PatternKit.Generators.Abstractions/Repository/RepositoryAttributes.cs | Adds public attribute API surface for the repository generator. |
| src/PatternKit.Examples/RepositoryDemo/OrderRepositoryDemo.cs | Adds the order repository example, DI extension, and a generated factory host. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitPatternCatalog.cs | Adds Repository pattern entry and links to runtime/generator/docs/tests/example. |
| src/PatternKit.Examples/ProductionReadiness/PatternKitExampleCatalog.cs | Adds “Order Repository Pattern” example descriptor and metadata. |
| src/PatternKit.Examples/DependencyInjection/PatternKitExampleServiceCollectionExtensions.cs | Wires the repository example into the examples DI registry. |
| src/PatternKit.Core/Application/Repository/Repository.cs | Adds runtime repository abstraction, in-memory implementation, and result/status models. |
| docs/patterns/toc.yml | Adds Repository to the patterns TOC under Application Architecture. |
| docs/patterns/application/repository.md | Adds Repository pattern documentation and generator overview. |
| docs/guides/pattern-coverage.md | Updates pattern coverage matrix to include Repository. |
| docs/generators/toc.yml | Adds Repository generator docs to generator TOC. |
| docs/generators/repository.md | Adds generator documentation and diagnostics table for PKREP001–PKREP003. |
| docs/generators/index.md | Lists Repository in the generator index table. |
| docs/examples/toc.yml | Adds “Order Repository Pattern” to the examples TOC. |
| docs/examples/order-repository-pattern.md | Adds example documentation for DI import + workflow usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// <summary>In-memory repository implementation for tests, samples, and embedded applications.</summary> | ||
| public sealed class InMemoryRepository<TEntity, TKey> : IRepository<TEntity, TKey> | ||
| where TKey : notnull | ||
| { | ||
| private readonly Dictionary<TKey, TEntity> _entities; | ||
| private readonly Func<TEntity, TKey> _keySelector; | ||
|
|
||
| private InMemoryRepository(Func<TEntity, TKey> keySelector, IEqualityComparer<TKey>? comparer) | ||
| { | ||
| _keySelector = keySelector ?? throw new ArgumentNullException(nameof(keySelector)); | ||
| _entities = new Dictionary<TKey, TEntity>(comparer); | ||
| } |
| services.AddSingleton<IRepository<OrderRecord, string>>(_ => OrderRepositoryPolicies.CreateFluentRepository()); | ||
| services.AddSingleton<OrderRepositoryWorkflow>(); |
| context.AddSource($"{type.Name}.Repository.g.cs", SourceText.From( | ||
| GenerateSource(type, entityType, keyType, selector.Name, GetNamedString(attribute, "FactoryName") ?? "Create"), | ||
| Encoding.UTF8)); |
| ```csharp | ||
| var repository = InMemoryRepository<OrderRecord, string> | ||
| .Create(order => order.OrderId) | ||
| .UseComparer(StringComparer.OrdinalIgnoreCase) | ||
| .Build(); | ||
|
|
||
| await repository.AddAsync(order, ct); | ||
| var pending = await repository.FindAsync(PendingOrderSpecification, ct); | ||
| ``` |
| ```csharp | ||
| var services = new ServiceCollection(); | ||
| services.AddOrderRepositoryDemo(); | ||
|
|
||
| using var provider = services.BuildServiceProvider(); | ||
| var workflow = provider.GetRequiredService<OrderRepositoryWorkflow>(); | ||
| var summary = await workflow.RunAsync(); | ||
| ``` |
| [Scenario("Repository RejectsDuplicateAddsAndMissingUpdates")] | ||
| [Fact] |
| { | ||
| FactoryMethodName = "BuildSearchLimit", | ||
| PolicyName = "product-search", | ||
| PermitLimit = 10, | ||
| WindowMilliseconds = 1000 | ||
| }; | ||
| var repository = new GenerateRepositoryAttribute(typeof(string), typeof(Guid)) | ||
| { | ||
| FactoryName = "BuildRepository" | ||
| }; |
🔍 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. |
Summary
Closes #236.
Validation
Note: local examples build still hits the existing Roslyn analyzer/compiler mismatch (CS9057) and generated-type cascade; hosted CI validates the examples matrix.