[10.x] Add dependency resolver attributes #49640
Closed
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.
Premise of this PR
This PR adds the ability to have an implementation decide where to get dependencies from without explicit binding.
I often use the container for container to resolve services/actions etc in my code to have IoC but
find e.g. giving config values to those classes cumbersome, especially if all other dependencies
can be resolved by the container itself except one (api key for example).
An alternative would be contextual binding, but I personally don't like having references to parameters
that my IDE doesn't understand. Renaming it would probably break the code unless you search for it.
Of course having automated tests would prevent mistakes like that to a certain extend, but I often
mock my dependencies instead of letting them resolve.
This issue was addressed by #46530 but very specific to config.
This PR attempts to provide a more generic solution.
Examples
Before 1:
Before 2:
After:
No binding needed
Benchmarks
My main concern with adding this would be performance due to the usage of reflection, this was
actually not that bad in my opinion. Here are a few test cases, feel free to suggest more scenarios.
Tested on a 2023 M2 MacBook Air 16GB
Test 1:
Before: 0.001ms
After: 0.002ms
Test 2:
Before: 0.004ms
After: 0.005ms
Test 3:
Before: 0.007ms
After: 0.007ms
Breaking changes
As far as I can tell this does not break existing code.
Final thoughts
The performance was my main concern like I pointed out earlier. I however also don't know if this is
"too much" for the container, I have always seen the container as fairly straight forward and I think
this feature might lean more toward the "syntactic sugar"-side.
It might be worth it to add a setting to enable or disable this for people who which to avoid the
performance penalty caused by reflection. This will probably have to be set quite early in the
framework lifecycle to guaranty consistent results, not too sure.
Feel free to give feedback. Thanks