/**
* @param \Nette\DI\Container $dic
* @throws MemberAccessException
* @internal
*/
public function injectComponentFactories(Nette\DI\Container $dic)
{
if (!$this instanceof Nette\Application\UI\PresenterComponent && !$this instanceof Nette\Application\UI\Component) {
throw new MemberAccessException('Trait ' . __TRAIT__ . ' can be used only in descendants of PresenterComponent.');
}
$this->autowireComponentFactoriesLocator = $dic;
$storage = $dic->hasService('autowired.cacheStorage') ? $dic->getService('autowired.cacheStorage') : $dic->getByType('Nette\\Caching\\IStorage');
$cache = new Nette\Caching\Cache($storage, 'Kdyby.Autowired.AutowireComponentFactories');
if ($cache->load($presenterClass = get_class($this)) !== NULL) {
return;
}
$ignore = class_parents('Nette\\Application\\UI\\Presenter') + ['ui' => 'Nette\\Application\\UI\\Presenter'];
$rc = new ClassType($this);
foreach ($rc->getMethods() as $method) {
if (in_array($method->getDeclaringClass()->getName(), $ignore, TRUE) || !Strings::startsWith($method->getName(), 'createComponent')) {
continue;
}
foreach ($method->getParameters() as $parameter) {
if (!($class = $parameter->getClassName())) {
// has object type hint
continue;
}
if (!$this->findByTypeForFactory($class) && !$parameter->allowsNull()) {
throw new MissingServiceException("No service of type {$class} found. Make sure the type hint in {$method} is written correctly and service of this type is registered.");
}
}
}
$files = array_map(function ($class) {
return ClassType::from($class)->getFileName();
}, array_diff(array_values(class_parents($presenterClass) + ['me' => $presenterClass]), $ignore));
$files[] = ClassType::from($this->autowireComponentFactoriesLocator)->getFileName();
$cache->save($presenterClass, TRUE, [$cache::FILES => $files]);
}