-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modify how nested resolutions get cached #10
Conversation
Previously, calling `Container::get()` would set `Container::$cacheResolutions = true`, run `Container::make()`, then restore `Container::$cacheResolutions` to its default value of `false`. This worked well-enough for simple dependencies, but if the callable used to resolve a dependency used `get()` instead of `make()` then the resolution caching could be broken, resulting in warnings like the following: > PHP Warning: Undefined array key "some-abstract" in /path/to/Container.php This commit fixes the issue in two ways: 1. Replace the boolean `Container::$cacheResolutions` property with `Container::$resolutionCacheDepth`, an integer that gets incremented with each level of recursion * If this value is greater than 0, `make()` will automatically cache everything it resolves 2. Explicitly set `Container::$resolved[$abstract]` upon calling `get()` instead of relying on `make()` to set it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine, but moves us a little further down this weird global state tracking path. If this ends up causing more problems in the future, let me know and I feel we should refactor to make this more thread-safe, which should also make weird edge cases less of a problem. Still this approach is faster than what I loosely have in mind, and if it's doing its job, we're only in a single threaded environment so there's no reason to refactor.
src/Container.php
Outdated
/** | ||
* Whether or not resolutions should be cached. | ||
* | ||
* By default, this will be false but will be set to `true` when calling `get()`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* By default, this will be false but will be set to `true` when calling `get()`. | |
* By default, this will be `0` and will get incremented when calling `get()`. |
@@ -214,11 +219,9 @@ public function make($abstract) | |||
} else { | |||
throw new ContainerException(sprintf('Unhandled definition type (%s)', gettype($config[$abstract]))); | |||
} | |||
} catch (RecursiveDependencyException $e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this is much better. Good update.
That's definitely a path I'd like to look into when we have some more time 👍 |
Previously, calling
Container::get()
would setContainer::$cacheResolutions = true
, runContainer::make()
, then restoreContainer::$cacheResolutions
to its default value offalse
.This worked well-enough for simple dependencies, but if the callable used to resolve a dependency used
get()
instead ofmake()
then the resolution caching could be broken, resulting in warnings like the following:This PR fixes the issue in two ways:
Container::$cacheResolutions
property withContainer::$resolutionCacheDepth
, an integer that gets incremented with each level of recursionmake()
will automatically cache everything it resolvesContainer::$resolved[$abstract]
upon callingget()
instead of relying onmake()
to set it.