Merge pull request #7292 from sminnee/injector-dependency-speedup

FIX: Prevent repeated lookup of obj.dependencies by Injector
This commit is contained in:
Damian Mooyman 2017-08-22 14:30:35 +12:00 committed by GitHub
commit 179a9fca28

View File

@ -665,11 +665,11 @@ class Injector implements ContainerInterface
// now, use any cached information about what properties this object type has // now, use any cached information about what properties this object type has
// and set based on name resolution // and set based on name resolution
if (!$mapping) { if ($mapping === null) {
if ($this->autoScanProperties) { // we use an object to prevent array copies if/when passed around
// we use an object to prevent array copies if/when passed around $mapping = new ArrayObject();
$mapping = new ArrayObject();
if ($this->autoScanProperties) {
// This performs public variable based injection // This performs public variable based injection
$robj = new ReflectionObject($object); $robj = new ReflectionObject($object);
$properties = $robj->getProperties(); $properties = $robj->getProperties();
@ -704,34 +704,50 @@ class Injector implements ContainerInterface
} }
} }
} }
// we store the information about what needs to be injected for objects of this
// type here
$this->injectMap[get_class($object)] = $mapping;
} }
} else {
foreach ($mapping as $prop => $spec) { $injections = Config::inst()->get(get_class($object), 'dependencies');
if ($spec['type'] == 'property') { // If the type defines some injections, set them here
$value = $this->get($spec['name']); if ($injections && count($injections)) {
$object->$prop = $value; foreach ($injections as $property => $value) {
} else { // we're checking empty in case it already has a property at this name
$method = $prop; // this doesn't catch privately set things, but they will only be set by a setter method,
$value = $this->get($spec['name']); // which should be responsible for preventing further setting if it doesn't want it.
$object->$method($value); if (empty($object->$property)) {
$convertedValue = $this->convertServiceProperty($value);
$this->setObjectProperty($object, $property, $convertedValue);
$mapping[$property] = array('service' => $value, 'type' => 'service');
}
} }
} }
}
$injections = Config::inst()->get(get_class($object), 'dependencies'); // we store the information about what needs to be injected for objects of this
// If the type defines some injections, set them here // type here
if ($injections && count($injections)) { $this->injectMap[$objtype] = $mapping;
foreach ($injections as $property => $value) { } else {
// we're checking empty in case it already has a property at this name foreach ($mapping as $prop => $propSpec) {
// this doesn't catch privately set things, but they will only be set by a setter method, switch ($propSpec['type']) {
// which should be responsible for preventing further setting if it doesn't want it. case 'property':
if (empty($object->$property)) { $value = $this->get($propSpec['name']);
$value = $this->convertServiceProperty($value); $object->$prop = $value;
$this->setObjectProperty($object, $property, $value); break;
case 'method':
$method = $prop;
$value = $this->get($propSpec['name']);
$object->$method($value);
break;
case 'service':
if (empty($object->$prop)) {
$value = $this->convertServiceProperty($propSpec['service']);
$this->setObjectProperty($object, $prop, $value);
}
break;
default:
throw new \LogicException("Bad mapping type: " . $propSpec['type']);
} }
} }
} }