Skip to content

feat(host): add stream feature abstraction layer#181

Merged
j-d-ha merged 15 commits into
mainfrom
feature/#179-add-stream-feature-abstraction-layer
Nov 26, 2025
Merged

feat(host): add stream feature abstraction layer#181
j-d-ha merged 15 commits into
mainfrom
feature/#179-add-stream-feature-abstraction-layer

Conversation

@j-d-ha

@j-d-ha j-d-ha commented Nov 26, 2025

Copy link
Copy Markdown
Collaborator

🚀 Pull Request

📋 Summary

This PR refactors the invocation data handling in Lambda by replacing the direct RawInvocationData property with a feature-based approach using IInvocationDataFeature. This improves the abstraction and follows the existing feature pattern used throughout the framework.

Changes:

  • Replace RawInvocationData with IInvocationDataFeature feature in the feature collection
  • Create InvocationDataFeature and InvocationDataFeatureFactory implementations
  • Update all references to use context.Features.GetRequired<IInvocationDataFeature>()
  • Remove RawInvocationData class and references from public abstractions
  • Update source generator templates to use the new feature pattern
  • Update tests to accommodate the new approach

Benefits:

  • Consistent with the existing feature pattern in the framework
  • Better abstraction for stream handling
  • Improved testability and flexibility for stream management

✅ Checklist

  • My changes build cleanly
  • I've added/updated relevant tests
  • I've added/updated documentation or README
  • I've followed the coding style for this project
  • I've tested the changes locally (if applicable)

🧪 Related Issues or PRs

Closes #179


💬 Notes for Reviewers

The IInvocationDataFeature is registered in the DI container as a singleton factory. The feature is set up in the LambdaHandlerComposer for each invocation and properly disposed after use. All source generator snapshots have been updated to reflect the new pattern.

- Introduced `IInvocationDataFeatureFactory` to create features from event streams.
- Added `IInvocationDataFeature` to encapsulate raw Lambda event and response data streams.
- Added `InvocationDataFeatureFactory` to create `InvocationDataFeature` instances using event streams.
- Introduced `InvocationDataFeature` to manage event and response data streams, with proper disposal logic.
- Deleted `RawInvocationData` class and its documentation.
- Removed `RawInvocationData` usage from `ILambdaHostContext` and `ILambdaHostContextFactory`.
- Simplified APIs and cleaned up legacy code by eliminating raw data stream handling directly.
… response streams

- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream`.
- Replaced `RawInvocationData.Response` with `InvocationDataFeature.ResponseStream`.
- Replaced `RawInvocationData` with `InvocationDataFeature` in handler composition and context creation.
- Updated feature access to use `IInvocationDataFeature` for event and response stream management.
- Removed all references, properties, and methods related to `RawInvocationData`.
- Ensured proper dependency injection of `IInvocationDataFeatureFactory` where necessary.
…ature

- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream` in unit tests.
- Updated test arrangement to set up `IInvocationDataFeature` and its event stream mock.
- Eliminated all references to `RawInvocationData` in `DefaultLambdaHostContextTests`.
- Updated unit test parameters to exclude `RawInvocationData`.
- Adjusted affected test setups and assertions to align with the new API structure.
…ests

- Removed `RawInvocationData` from unit test parameters in `LambdaHostContextFactoryTests`.
- Updated test calls to align with the revised `Create` method signature.
- Adjusted test arrangements and assertions to match the updated API structure.
- Added `IInvocationDataFeatureFactory` and its implementation to the service collection.
- Ensured proper dependency injection for `InvocationDataFeatureFactory`.
- Added tests to ensure `Create` method returns `IInvocationDataFeature` instances.
- Verified `EventStream` is set to the provided stream during feature creation.
- Asserted `ResponseStream` is initialized as a `MemoryStream` for each feature.
- Ensured `Create` returns new feature instances with each call.
- Checked that created features implement `IDisposable`.
… stream

- Replaced hardcoded `response` strings with `testData` parameter in test arrangements.
- Introduced `[Frozen] Stream responseStream` to improve test reliability and mock setup.
- Updated assertions to validate `serializer` writes data to the frozen `responseStream`.
- Removed redundant variable declarations for response streams in test cases.
…daHandlerComposerTests

- Added tests to validate proper usage of `InvocationDataFeatureFactory` in `LambdaHandlerComposer`.
- Verified factory is invoked to create `IInvocationDataFeature` instances with response stream.
- Ensured factory is included in constructor null-parameter checks and test setups.
- Updated mock setup to generate `IInvocationDataFeature` with `MemoryStream` response.
…e count

- Converted `AddLambdaHostCoreServices_RegistersExactlyEightServices` to use `[Theory]` and `InlineData`.
- Parameterized test to accept `servicesCount` instead of hardcoding service registrations.
- Updated assertion to validate dynamic `servicesCount` rather than fixed value.
- Replaced `RawInvocationData.Response` with `InvocationDataFeature.ResponseStream` in snapshot tests.
- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream` in snapshot tests.
- Ensured alignment with the updated API using `IInvocationDataFeature` for streams.
@github-actions github-actions Bot added the type: feat New feature label Nov 26, 2025
- Marked `DefaultLambdaHostContext` and `InvocationDataFeature` as `sealed` for performance improvements.
- Ensured classes are no longer inheritable to communicate final design decisions.
@sonarqubecloud

Copy link
Copy Markdown

@j-d-ha
j-d-ha merged commit b6e3399 into main Nov 26, 2025
6 checks passed
@j-d-ha
j-d-ha deleted the feature/#179-add-stream-feature-abstraction-layer branch November 26, 2025 20:58
j-d-ha added a commit that referenced this pull request Nov 26, 2025
* feat(lambda): add interfaces for invocation data feature

- Introduced `IInvocationDataFeatureFactory` to create features from event streams.
- Added `IInvocationDataFeature` to encapsulate raw Lambda event and response data streams.

* feat(lambda): implement invocation data feature factory

- Added `InvocationDataFeatureFactory` to create `InvocationDataFeature` instances using event streams.
- Introduced `InvocationDataFeature` to manage event and response data streams, with proper disposal logic.

* refactor(lambda): remove RawInvocationData and related references

- Deleted `RawInvocationData` class and its documentation.
- Removed `RawInvocationData` usage from `ILambdaHostContext` and `ILambdaHostContextFactory`.
- Simplified APIs and cleaned up legacy code by eliminating raw data stream handling directly.

* refactor(lambda): update usage to InvocationDataFeature for event and response streams

- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream`.
- Replaced `RawInvocationData.Response` with `InvocationDataFeature.ResponseStream`.

* refactor(lambda): integrate InvocationDataFeature across lambda handling

- Replaced `RawInvocationData` with `InvocationDataFeature` in handler composition and context creation.
- Updated feature access to use `IInvocationDataFeature` for event and response stream management.
- Removed all references, properties, and methods related to `RawInvocationData`.
- Ensured proper dependency injection of `IInvocationDataFeatureFactory` where necessary.

* test(lambda): update DefaultEventFeatureTests to use InvocationDataFeature

- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream` in unit tests.
- Updated test arrangement to set up `IInvocationDataFeature` and its event stream mock.

* test(lambda): remove RawInvocationData references in unit tests

- Eliminated all references to `RawInvocationData` in `DefaultLambdaHostContextTests`.
- Updated unit test parameters to exclude `RawInvocationData`.
- Adjusted affected test setups and assertions to align with the new API structure.

* test(lambda): remove RawInvocationData from LambdaHostContextFactoryTests

- Removed `RawInvocationData` from unit test parameters in `LambdaHostContextFactoryTests`.
- Updated test calls to align with the revised `Create` method signature.
- Adjusted test arrangements and assertions to match the updated API structure.

* feat(lambda): register InvocationDataFeatureFactory in DI

- Added `IInvocationDataFeatureFactory` and its implementation to the service collection.
- Ensured proper dependency injection for `InvocationDataFeatureFactory`.

* test(lambda): add unit tests for InvocationDataFeatureFactory

- Added tests to ensure `Create` method returns `IInvocationDataFeature` instances.
- Verified `EventStream` is set to the provided stream during feature creation.
- Asserted `ResponseStream` is initialized as a `MemoryStream` for each feature.
- Ensured `Create` returns new feature instances with each call.
- Checked that created features implement `IDisposable`.

* test(lambda): update DefaultResponseFeatureTests with frozen response stream

- Replaced hardcoded `response` strings with `testData` parameter in test arrangements.
- Introduced `[Frozen] Stream responseStream` to improve test reliability and mock setup.
- Updated assertions to validate `serializer` writes data to the frozen `responseStream`.
- Removed redundant variable declarations for response streams in test cases.

* test(lambda): add unit tests for InvocationDataFeatureFactory in LambdaHandlerComposerTests

- Added tests to validate proper usage of `InvocationDataFeatureFactory` in `LambdaHandlerComposer`.
- Verified factory is invoked to create `IInvocationDataFeature` instances with response stream.
- Ensured factory is included in constructor null-parameter checks and test setups.
- Updated mock setup to generate `IInvocationDataFeature` with `MemoryStream` response.

* test(lambda): parameterize AddLambdaHostCoreServices test with service count

- Converted `AddLambdaHostCoreServices_RegistersExactlyEightServices` to use `[Theory]` and `InlineData`.
- Parameterized test to accept `servicesCount` instead of hardcoding service registrations.
- Updated assertion to validate dynamic `servicesCount` rather than fixed value.

* test(lambda): update snapshots to use InvocationDataFeature streams

- Replaced `RawInvocationData.Response` with `InvocationDataFeature.ResponseStream` in snapshot tests.
- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream` in snapshot tests.
- Ensured alignment with the updated API using `IInvocationDataFeature` for streams.

* refactor(lambda): seal context and feature classes

- Marked `DefaultLambdaHostContext` and `InvocationDataFeature` as `sealed` for performance improvements.
- Ensured classes are no longer inheritable to communicate final design decisions.
j-d-ha added a commit that referenced this pull request Nov 27, 2025
…ormats (#184)

* refactor(envelopes): extract abstract base for API Gateway envelopes

- Introduced `ApiGatewayRequestEnvelopeBase` as an abstract base class for strongly typed deserialization.
- Updated `ApiGatewayRequestEnvelope` to inherit from the new base class.
- Simplified `ApiGatewayRequestEnvelope` by moving shared logic to the base class.

* feat(options): extend EnvelopeOptions with XML serialization settings

- Added `XmlReaderSettings` to support customized XML deserialization for Lambda event payloads.
- Added `XmlWriterSettings` to support customized XML serialization for Lambda event payloads.
- Introduced `Items` dictionary to allow storing custom extension data for envelope processing.

* feat(options): add base64 encoding/decoding options to EnvelopeOptions

- Introduced `DecodeFromBase64` to toggle base64 decoding for payloads.
- Introduced `EncodeToBase64` to toggle base64 encoding for payloads.
- Both properties default to `null`, preserving existing behavior unless explicitly configured.

* feat(templates): add GitHub issue and discussion templates (#176)

- Added config.yml to disable blank issues and provide helpful contact links.
- Created discussion templates (general, idea, and Q&A) for better community engagement.
- Added issue templates for feature requests and bug reports to standardize issue reporting.

* feat(core): add ILambdaHostContextAccessor and context factory integration (#178)

* feat(core): add ILambdaHostContextAccessor interface

- Introduces an interface for accessing the ILambdaHostContext during Lambda invocations.
- Facilitates dependency injection by eliminating the need to pass context through method parameters.

* feat(core): implement LambdaHostContextAccessor

- Adds LambdaHostContextAccessor for managing ILambdaHostContext access.
- Utilizes AsyncLocal to store and retrieve context during Lambda executions.

* feat(core): add LambdaHostContextFactory and related interface

- Introduces ILambdaHostContextFactory for creating Lambda host contexts.
- Implements LambdaHostContextFactory to manage ILambdaHostContext instantiation.
- Ensures proper dependency injection of required services like IServiceScopeFactory.

* refactor(core): replace FeatureCollectionFactory with LambdaHostContextFactory

- Removed IFeatureCollectionFactory dependency from LambdaHandlerComposer.
- Introduced ILambdaHostContextFactory to streamline Lambda context creation.
- Updated lambda invocation flow to use LambdaHostContextFactory for context management.
- Ensured proper IDisposable handling for LambdaHostContext instances.

* feat(core): add LambdaHostContextAccessor and extend DI support

- Introduced AddLambdaHostContextAccessor method to register ILambdaHostContextAccessor.
- Registered ILambdaHostContextFactory in the service collection for enhanced DI.

* feat(core): add AddLambdaHostContextAccessor extension method

- Registers ILambdaHostContextAccessor as a singleton in the DI container.
- Enables application-wide access to ILambdaHostContext via dependency injection.

* test(builder): add unit tests for AddLambdaHostContextAccessor method

- Validates null IServiceCollection throws ArgumentNullException.
- Confirms IServiceCollection chaining works as expected.
- Ensures ILambdaHostContextAccessor is registered as a singleton.
- Verifies implementation type is LambdaHostContextAccessor.

* refactor(core): make ILambdaHostContextAccessor optional in LambdaHostContextFactory

- Updated constructor to set ILambdaHostContextAccessor as an optional parameter.
- Improves flexibility by allowing null values for ILambdaHostContextAccessor.

* test(core): add unit tests for LambdaHostContextFactory

- Validates null IServiceScopeFactory throws ArgumentNullException.
- Validates null IFeatureCollectionFactory throws ArgumentNullException.
- Confirms successful construction with valid dependencies.
- Verifies Create calls FeatureCollectionFactory.Create.
- Ensures context accessor gets updated when provided.

* chore(core): update license references for third-party code

- Added license notice and source reference to LambdaHostContextAccessor.
- Updated license URL in LambdaApplicationBuilder for consistency with aspnetcore.

* test(core): add unit tests for LambdaHostContextAccessor

- Validates LambdaHostContext returns null when not set.
- Confirms LambdaHostContext retains and returns assigned values.
- Verifies LambdaHostContext updates to new values and reflects changes.
- Ensures LambdaHostContext becomes null when explicitly set to null.
- Confirms multiple instances share AsyncLocal state and reflect latest value.

* test(core): update unit tests to use LambdaHostContextFactory

- Replaced IFeatureCollectionFactory with ILambdaHostContextFactory in unit tests.
- Removed tests specific to IFeatureCollectionFactory as it was deprecated.
- Added mocks and test cases for LambdaHostContextFactory.
- Ensured proper disposal testing with IAsyncDisposable for LambdaHostContext.
- Updated constructor parameter validation tests to reflect new dependencies.

* chore(build): bump VersionPrefix to 1.0.1-beta.4

- Updated Directory.Build.props to reflect the new pre-release version.

* feat(host): add stream feature abstraction layer (#181)

* feat(lambda): add interfaces for invocation data feature

- Introduced `IInvocationDataFeatureFactory` to create features from event streams.
- Added `IInvocationDataFeature` to encapsulate raw Lambda event and response data streams.

* feat(lambda): implement invocation data feature factory

- Added `InvocationDataFeatureFactory` to create `InvocationDataFeature` instances using event streams.
- Introduced `InvocationDataFeature` to manage event and response data streams, with proper disposal logic.

* refactor(lambda): remove RawInvocationData and related references

- Deleted `RawInvocationData` class and its documentation.
- Removed `RawInvocationData` usage from `ILambdaHostContext` and `ILambdaHostContextFactory`.
- Simplified APIs and cleaned up legacy code by eliminating raw data stream handling directly.

* refactor(lambda): update usage to InvocationDataFeature for event and response streams

- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream`.
- Replaced `RawInvocationData.Response` with `InvocationDataFeature.ResponseStream`.

* refactor(lambda): integrate InvocationDataFeature across lambda handling

- Replaced `RawInvocationData` with `InvocationDataFeature` in handler composition and context creation.
- Updated feature access to use `IInvocationDataFeature` for event and response stream management.
- Removed all references, properties, and methods related to `RawInvocationData`.
- Ensured proper dependency injection of `IInvocationDataFeatureFactory` where necessary.

* test(lambda): update DefaultEventFeatureTests to use InvocationDataFeature

- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream` in unit tests.
- Updated test arrangement to set up `IInvocationDataFeature` and its event stream mock.

* test(lambda): remove RawInvocationData references in unit tests

- Eliminated all references to `RawInvocationData` in `DefaultLambdaHostContextTests`.
- Updated unit test parameters to exclude `RawInvocationData`.
- Adjusted affected test setups and assertions to align with the new API structure.

* test(lambda): remove RawInvocationData from LambdaHostContextFactoryTests

- Removed `RawInvocationData` from unit test parameters in `LambdaHostContextFactoryTests`.
- Updated test calls to align with the revised `Create` method signature.
- Adjusted test arrangements and assertions to match the updated API structure.

* feat(lambda): register InvocationDataFeatureFactory in DI

- Added `IInvocationDataFeatureFactory` and its implementation to the service collection.
- Ensured proper dependency injection for `InvocationDataFeatureFactory`.

* test(lambda): add unit tests for InvocationDataFeatureFactory

- Added tests to ensure `Create` method returns `IInvocationDataFeature` instances.
- Verified `EventStream` is set to the provided stream during feature creation.
- Asserted `ResponseStream` is initialized as a `MemoryStream` for each feature.
- Ensured `Create` returns new feature instances with each call.
- Checked that created features implement `IDisposable`.

* test(lambda): update DefaultResponseFeatureTests with frozen response stream

- Replaced hardcoded `response` strings with `testData` parameter in test arrangements.
- Introduced `[Frozen] Stream responseStream` to improve test reliability and mock setup.
- Updated assertions to validate `serializer` writes data to the frozen `responseStream`.
- Removed redundant variable declarations for response streams in test cases.

* test(lambda): add unit tests for InvocationDataFeatureFactory in LambdaHandlerComposerTests

- Added tests to validate proper usage of `InvocationDataFeatureFactory` in `LambdaHandlerComposer`.
- Verified factory is invoked to create `IInvocationDataFeature` instances with response stream.
- Ensured factory is included in constructor null-parameter checks and test setups.
- Updated mock setup to generate `IInvocationDataFeature` with `MemoryStream` response.

* test(lambda): parameterize AddLambdaHostCoreServices test with service count

- Converted `AddLambdaHostCoreServices_RegistersExactlyEightServices` to use `[Theory]` and `InlineData`.
- Parameterized test to accept `servicesCount` instead of hardcoding service registrations.
- Updated assertion to validate dynamic `servicesCount` rather than fixed value.

* test(lambda): update snapshots to use InvocationDataFeature streams

- Replaced `RawInvocationData.Response` with `InvocationDataFeature.ResponseStream` in snapshot tests.
- Replaced `RawInvocationData.Event` with `InvocationDataFeature.EventStream` in snapshot tests.
- Ensured alignment with the updated API using `IInvocationDataFeature` for streams.

* refactor(lambda): seal context and feature classes

- Marked `DefaultLambdaHostContext` and `InvocationDataFeature` as `sealed` for performance improvements.
- Ensured classes are no longer inheritable to communicate final design decisions.

* chore(workflows): pinned release-drafter action to 6.0.0 (#182)

* fix(ci): add explicit token to checkout and create-pull-request actions (#183)

* fix(ci): add explicit token to checkout and create-pull-request actions

* chore(release): update changelog for v1.1.0

- Add entries for features, bug fixes, documentation, and maintenance for v1.1.0.
- Update version comparison links to v1.1.0.
- Include `.gitignore` update to ignore `temp.md`.

* refactor(options): remove base64 encoding/decoding properties from EnvelopeOptions

- Removed `DecodeFromBase64` and `EncodeToBase64` as they are no longer needed.
- Simplified the `EnvelopeOptions` class to streamline property management.

* refactor(envelopes): make ApiGatewayRequestEnvelope sealed

- Updated `ApiGatewayRequestEnvelope<T>` to be `sealed` to prevent further inheritance.
- Added remarks to `ExtractPayload` method clarifying JSON deserialization behavior.

* refactor(envelopes): apply abstract base class pattern to remaining envelopes

Refactor ApiGatewayV2RequestEnvelope, ApiGatewayResponseEnvelope,
ApiGatewayV2ResponseEnvelope, and SqsEnvelope to follow the same
abstract base class pattern as ApiGatewayRequestEnvelope.

This provides:
- Consistency across all envelope implementations
- Sealed concrete classes for better encapsulation
- Foundation for supporting multiple serialization formats
- Centralized payload handling logic in base classes

* refactor(envelopes): adjust formatting of base class declarations

- Reformatted `ApiGatewayV2RequestEnvelopeBase` and `ApiGatewayV2ResponseEnvelopeBase` for improved readability.
- Applied consistent line-breaking style for multi-line `base class` and `interface` declarations.
- Clarified existing remarks without modifying logic or functionality.

* docs(envelopes): add examples for custom XML envelopes

- Documented the process for implementing custom deserialization and serialization logic.
- Provided code examples for XML-based request and response envelopes.
- Clarified how to support multiple formats while preserving the envelope interface.

* docs(envelopes): add example for custom deserialization in SQS envelopes

- Documented how to extend `SqsEnvelopeBase<T>` for custom deserialization logic.
- Added an XML deserialization example using `SqsXmlEnvelope<T>`.
- Explained support for multiple serialization formats with a consistent envelope interface.

* docs(envelopes): add root README and update package-specific documentation

- Added `src/Envelopes/README.md` to provide an overview of envelopes, their benefits, and usage.
- Updated package-specific READMEs to include links to related packages for better navigation.
- Registered `src/Envelopes/README.md` in the solution file for improved project visibility.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(host): add stream feature abstraction layer

1 participant