Skip to content

Add decorator registration support with compile-time validation#303

Merged
pwelter34 merged 8 commits intomainfrom
claude/plan-decorator-pattern-wJnyV
Apr 28, 2026
Merged

Add decorator registration support with compile-time validation#303
pwelter34 merged 8 commits intomainfrom
claude/plan-decorator-pattern-wJnyV

Conversation

@pwelter34
Copy link
Copy Markdown
Member

Summary

This PR adds comprehensive decorator registration support to Injectio, allowing services to be wrapped with decorators without runtime dependencies. The implementation includes a new RegisterDecorator attribute, compile-time diagnostics for decorator validation, and code generation for decorator application.

Key Changes

  • New RegisterDecorator Attribute: Added RegisterDecoratorAttribute to mark classes as decorators for existing services, supporting:

    • Generic and non-generic service type specification
    • Keyed service decoration (with specific keys or AnyKey)
    • Custom factory methods for decorator instantiation
    • Decorator ordering via Order property
    • Tag-based filtering
    • Open generic service decoration
  • Compile-Time Validation: Extended ServiceRegistrationAnalyzer with decorator-specific diagnostics:

    • INJ0010: Decorator does not implement service type
    • INJ0011: Missing service type specification
    • INJ0012: Missing inner service constructor parameter
    • INJ0013: Factory method not found
    • INJ0014: Factory method has invalid signature
    • INJ0015: Open-generic + keyed combination (unsupported)
    • INJ0016: Decorated service not registered (when no dynamic modules present)
  • Code Generation:

    • Extended ServiceRegistrationWriter to generate decorator registration calls
    • Added GenerateDecorationHelper() to emit decoration extension methods (Decorate<T>, DecorateKeyed<T>, DecorateOpenGeneric)
    • Decorators are applied in order and inherit the lifetime of the decorated service
    • Support for both automatic instantiation via ActivatorUtilities and custom factory methods
  • Analyzer Enhancement: Implemented AnalyzeCompilation to perform cross-symbol analysis:

    • Collects all decorator registrations and registered service types
    • Validates decorator constraints at compilation end
    • Detects unregistered service targets (when no dynamic modules exist)
  • Test Coverage: Added comprehensive test suite (ServiceRegistrationDecoratorTests) with:

    • Simple decorator registration
    • Generic attribute syntax
    • Chained decorators with ordering
    • Keyed service decoration
    • AnyKey decoration
    • Custom factory methods
    • Open generic decorators
    • Tag-based filtering
    • All diagnostic scenarios

Notable Implementation Details

  • Decorators use a thread-safe collection pattern with locks during compilation analysis
  • The decoration helper is only emitted when decorators are present
  • Decorator ordering is deterministic (by service type, order value, then decorator type name)
  • Open generic + keyed combination is explicitly rejected as unsupported
  • Unregistered service detection only applies when no service modules could dynamically register services

https://claude.ai/code/session_01DFMTsCCwsWoYM7vWumE6mw

Adds RegisterDecoratorAttribute (non-generic and generic variants) for
wrapping existing service registrations with decorator classes. The
generator emits a self-contained runtime helper (Injectio.Decoration.g.cs)
so no new package dependencies are introduced.

- Supports chaining via Order (lower = innermost)
- Supports keyed decoration, AnyKey, open-generic (closed instances),
  factory-built decorators, and tag filtering
- Adds diagnostics INJ0010-INJ0016 for decorator validation
- Runtime helpers use ActivatorUtilities for DI-friendly construction

https://claude.ai/code/session_01DFMTsCCwsWoYM7vWumE6mw
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 22, 2026

Coverage Report for CI Build 25031366509

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+2.7%) to 89.254%

Details

  • Coverage increased (+2.7%) from the base build.
  • Patch coverage: 46 uncovered changes across 4 files (675 of 721 lines covered, 93.62%).
  • 3 coverage regressions across 2 files.

Uncovered Changes

File Changed Covered %
src/Injectio.Generators/ServiceRegistrationAnalyzer.cs 277 251 90.61%
src/Injectio.Generators/ServiceRegistrationGenerator.cs 253 239 94.47%
src/Injectio.Generators/ServiceRegistrationWriter.cs 106 101 95.28%
src/Injectio.Generators/Infrastructure/CollectionBuilderAttribute.cs 1 0 0.0%

Coverage Regressions

3 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
src/Injectio.Generators/SymbolHelpers.cs 2 88.32%
src/Injectio.Generators/ServiceRegistrationGenerator.cs 1 88.8%

Coverage Stats

Coverage Status
Relevant Lines: 1501
Covered Lines: 1407
Line Coverage: 93.74%
Relevant Branches: 872
Covered Branches: 711
Branch Coverage: 81.54%
Branches in Coverage %: Yes
Coverage Strength: 75.36 hits per line

💛 - Coveralls

@pwelter34 pwelter34 marked this pull request as draft April 22, 2026 14:07
@pwelter34 pwelter34 marked this pull request as ready for review April 28, 2026 02:56
@pwelter34 pwelter34 merged commit 9cf52f8 into main Apr 28, 2026
7 checks passed
@pwelter34 pwelter34 deleted the claude/plan-decorator-pattern-wJnyV branch April 28, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants