Skip to content

Add decorator registration support with compile-time validation#303

Draft
pwelter34 wants to merge 2 commits intomainfrom
claude/plan-decorator-pattern-wJnyV
Draft

Add decorator registration support with compile-time validation#303
pwelter34 wants to merge 2 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 24800355082

Coverage increased (+0.8%) to 87.278%

Details

  • Coverage increased (+0.8%) from the base build.
  • Patch coverage: 51 uncovered changes across 4 files (535 of 586 lines covered, 91.3%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
src/Injectio.Generators/ServiceRegistrationAnalyzer.cs 276 250 90.58%
src/Injectio.Generators/ServiceRegistrationGenerator.cs 94 81 86.17%
src/Injectio.Attributes/RegisterDecoratorAttribute.cs 7 0 0.0%
src/Injectio.Generators/ServiceRegistrationWriter.cs 130 125 96.15%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1464
Covered Lines: 1331
Line Coverage: 90.92%
Relevant Branches: 902
Covered Branches: 734
Branch Coverage: 81.37%
Branches in Coverage %: Yes
Coverage Strength: 20.0 hits per line

💛 - Coveralls

@pwelter34 pwelter34 marked this pull request as draft April 22, 2026 14:07
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