Fix injecting reducer-backed read models into commands#2304
Merged
Conversation
AddReadModels only built its command-scope read model registrations from projections and model-bound projections, so a read model materialized by an IReducerFor<T> reducer was never registered. Injecting one into a CommandValidator<>, Provide(), or Handle() then failed at runtime even though the read model existed, while the identical projection-backed read model worked. Include reducer-backed read model types in the registered set so they resolve by key through IReadModels exactly like projection-backed ones. Extract the backing-kind extraction into a ReadModelTargetsFrom helper so the registration set is a single union and a future backing kind is one line. Registration stays scoped to read models with a Chronicle backing artifact and deliberately does not register by the Arc-level [ReadModel] attribute alone, since that attribute does not imply Chronicle key resolution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cover the registration, by-key resolution, and end-to-end command pipeline behavior for reducer-backed read models, alongside the existing projection and model-bound coverage: - when_adding_read_models asserts scoped resolvers are registered for projection-, model-bound-, and reducer-backed read models. - when_resolving_a_reducer_read_model_through_di drives the real DI registration and resolves a reducer read model to its materialized instance, and to null when absent. - when_injecting_a_reducer_backed_read_model runs the real command pipeline and in-process Chronicle event log (mocking only the IReadModels boundary) and verifies injection into a CommandValidator<> (active and frozen), Handle(), Provide(), and a nullable Handle() parameter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clarify in the read models guide that command-scope injection works for read models backed by a projection, model-bound projection, or reducer, and explain that the [ReadModel] attribute alone does not make a read model injectable — key resolution is owned by the backing provider. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
NuGet packages for this PR, e.g. Cratis.Arc: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixed
IReducerFor<T>) read model into a command'sCommandValidator<>,Provide(), orHandle()no longer fails at runtime. Reducer-backed read models are now registered for command-scope resolution and resolve by key just like projection-backed and model-bound read models, including the nullable "does not exist" behavior.