Fix #17722: Add action injection support

This commit is contained in:
Sam
2020-06-12 09:06:18 +02:00
committed by GitHub
parent c365f472cd
commit 4ea484ca68
10 changed files with 391 additions and 9 deletions

View File

@@ -523,4 +523,34 @@ class Controller extends Component implements ViewContextInterface
return $path;
}
/**
* Fills parameters based on types and names in action method signature.
* @param \ReflectionType $type The reflected type of the action parameter.
* @param string $name The name of the parameter.
* @param array &$args The array of arguments for the action, this function may append items to it.
* @param array &$requestedParams The array with requested params, this function may write specific keys to it.
* @throws ErrorException when we cannot load a required service.
* @throws \yii\base\InvalidConfigException Thrown when there is an error in the DI configuration.
* @throws \yii\di\NotInstantiableException Thrown when a definition cannot be resolved to a concrete class
* (for example an interface type hint) without a proper definition in the container.
* @since 2.0.36
*/
final protected function bindInjectedParams(\ReflectionType $type, $name, &$args, &$requestedParams)
{
// Since it is not a builtin type it must be DI injection.
$typeName = $type->getName();
if (($component = $this->module->get($name, false)) instanceof $typeName) {
$args[] = $component;
$requestedParams[$name] = "Component: " . get_class($component) . " \$$name";
} elseif (\Yii::$container->has($typeName) && ($service = \Yii::$container->get($typeName)) instanceof $typeName) {
$args[] = $service;
$requestedParams[$name] = "DI: $typeName \$$name";
} elseif ($type->allowsNull()) {
$args[] = null;
$requestedParams[$name] = "Unavailable service: $name";
} else {
throw new Exception('Could not load required service: ' . $name);
}
}
}