Skip to content

Commit

Permalink
added check for cyclic dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelog committed Feb 27, 2012
1 parent 39283be commit 69096d3
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/mg/Ding/Container/Impl/ContainerImpl.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ class ContainerImpl implements IContainer
*/
private $_properties;

/**
* Horrible state keeper for getBeanDefinition() to avoid following cyclic
* dependencies.
* @var string[]
*/
private $_definitionsInProcess = array();

/**
* Prevent serialization.
*
Expand Down Expand Up @@ -581,18 +588,27 @@ private function _applyAspects(BeanDefinition $definition)
*/
private function _createBean(BeanDefinition $definition)
{
$name = $definition->getName();
if (isset($this->_definitionsInProcess[$name])) {
throw new BeanFactoryException(
"Cyclic dependency found for: $name"
);
}
$this->_definitionsInProcess[$name] = '';
$this->_lifecycleManager->beforeCreate($definition);
$this->_createBeanDependencies($definition);
$this->_applyAspects($definition);
$bean = $this->_instantiate($definition);
if (!is_object($bean)) {
unset($this->_definitionsInProcess[$name]);
throw new BeanFactoryException(
'Could not instantiate ' . $definition->getName()
);
}
$this->_assemble($bean, $definition);
$this->_setupInitAndShutdown($bean, $definition);
$this->_lifecycleManager->afterCreate($bean, $definition);
unset($this->_definitionsInProcess[$name]);
return $bean;
}

Expand Down
18 changes: 18 additions & 0 deletions test/container/Test_Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ public function cannot_create_bean_if_factory_method_returns_non_object()
$container = ContainerImpl::getInstance($this->_properties);
$bean = $container->getBean('cantCreate');
}

/**
* @test
* @expectedException Ding\Bean\Factory\Exception\BeanFactoryException
*/
public function cannot_create_with_cyclic_dependencies()
{
$container = ContainerImpl::getInstance($this->_properties);
$bean = $container->getBean('cyclicDependency1');
}
}

class SomeContainerTestBeanClass
Expand All @@ -168,6 +178,14 @@ class SomeContainerTestAspectClass

}

class CyclicDependencyClass
{
public $arg;
public function __construct(CyclicDependencyClass $arg)
{
$this->arg = $arg;
}
}
class AnInvalidFactory
{
public function invalidMethod()
Expand Down
6 changes: 6 additions & 0 deletions test/resources/container.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,11 @@
<property name="inexistant"><value>value</value></property>
</bean>
<bean id="invalidFactory" class="AnInvalidFactory"/>
<bean id="cyclicDependency1" class="CyclicDependencyClass">
<constructor-arg><ref bean="cyclicDependency2"/></constructor-arg>
</bean>
<bean id="cyclicDependency2" class="CyclicDependencyClass">
<constructor-arg><ref bean="cyclicDependency1"/></constructor-arg>
</bean>
<bean id="cantCreate" factory-bean="invalidFactory" factory-method="invalidMethod"/>
</beans>

0 comments on commit 69096d3

Please sign in to comment.