Split Resolver into focused contracts (Resolver, Reflector, Augmenter)#27
Draft
henriquemoody wants to merge 3 commits into
Draft
Split Resolver into focused contracts (Resolver, Reflector, Augmenter)#27henriquemoody wants to merge 3 commits into
henriquemoody wants to merge 3 commits into
Conversation
Unlike the resolver, which completes a call by padding gaps with defaults or null, the augmenter keeps the given arguments authoritative and only adds container services for parameters left unfilled. This suits factories that pass user input straight to a constructor. Types listed as unresolvable are never looked up in the container, which keeps value-like classes (clocks, dates) from being served as frozen services. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The static helpers reflectCallable() and acceptsType() do not depend on the container and are useful on their own. Moving them to a dedicated Reflector lets the next step reduce the Resolver to its resolution contract. The Resolver copies remain until that refactoring lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Consumers should depend on the resolution contract, not on the PSR-11 implementation, mirroring the Augmenter/ContainerAugmenter split. The concrete class becomes ContainerResolver, and the static helpers that already moved to Reflector are dropped from it. This is a breaking change, so the branch now aliases to 2.0.x-dev. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
|
I'll wait for your response in #26. If we don't introduce another kind of resolving, I would prefer keeping it contained in a single class. Even after merging augmenter+resolver as I proposed in the diff, Resolver.php stays very small at less than 300 lines. IMHO, introducing _other kinds of resolving* complicates things more than the benefit obtained by separating responsibilities. I could be wrong though, and maybe you have a plan or a use case that my comment on #26 does not address, or perhaps a better reasoning for making the architecture larger. I'm all ears! |
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.
Summary
Reshapes the package around small, single-purpose contracts so consumers
depend on behaviour, not on the PSR-11 implementation. The
Resolverbecomesan interface, the container-free reflection helpers move out into their own
class, and a new
Augmentercontract covers the factory use case the resolverwas never meant to serve.
This is a breaking change; the branch aliases to
2.0.x-dev.Changes
Introduce the
AugmentercontractAugmenterinterface andContainerAugmenterimplementation.or
null— the augmenter keeps the given arguments authoritative: neverrebound, reordered, or padded. It only fills genuinely unfilled parameters
with container services, added as named arguments.
extra arguments pass through unchanged.
unresolvableTypesare never looked up in the container,which keeps value-like classes (clocks, dates) from being served as frozen
services.
Extract
ReflectorfromResolverreflectCallable()andacceptsType()don't depend on the container and areuseful on their own, so they move to a dedicated
Reflector.Turn
Resolverinto an interfaceResolveris now the resolution contract; the concrete PSR-11 class isContainerResolver, mirroring theAugmenter/ContainerAugmentersplit.Reflectorare dropped from the class.Upgrading from 1.x
Resolveris now an interface; instantiateContainerResolverinstead.Resolver::reflectCallable()andResolver::acceptsType()moved toReflector.Augmenter/ContainerAugmenterfill unfilled parameters withouttouching the given arguments.
Tests
ContainerAugmenterTestandReflectorTest;ResolverTestrenamed toContainerResolverTest.OptionalServiceConsumer,tests/fixtures/functions.php).🤖 Generated with Claude Code