Skip to content

Commit

Permalink
[DependencyInjection] refactored loaders
Browse files Browse the repository at this point in the history
 * refactored the import mechanism for better flexibility
 * added two methods to LoaderInterface: supports() and setResolver()
 * added a LoaderResolver interface
 * added a Loader base class
 * added new loaders: DelegatingLoader, PhpFileLoader, and ClosureLoader
  • Loading branch information
fabpot committed Jul 20, 2010
1 parent 4e3e86c commit 60c6827
Show file tree
Hide file tree
Showing 21 changed files with 775 additions and 52 deletions.
@@ -0,0 +1,46 @@
<?php

namespace Symfony\Components\DependencyInjection\Loader;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* ClosureLoader loads service definitions from a PHP closure.
*
* The Closure has access to the container as its first argument.
*
* @package Symfony
* @subpackage Components_DependencyInjection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ClosureLoader extends Loader
{
/**
* Loads a Closure.
*
* @param \Closure $resource The resource
*/
public function load($closure)
{
call_user_func($closure, $this->container);
}

/**
* Returns true if this class supports the given resource.
*
* @param mixed $resource A resource
*
* @return Boolean true if this class supports the given resource, false otherwise
*/
public function supports($resource)
{
return $resource instanceof \Closure;
}
}
@@ -0,0 +1,68 @@
<?php

namespace Symfony\Components\DependencyInjection\Loader;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* DelegatingLoader delegates loading to other loaders using a loader resolver.
*
* @package Symfony
* @subpackage Components_DependencyInjection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class DelegatingLoader extends Loader
{
protected $resolver;

/**
* Constructor.
*
* @param \Symfony\Components\DependencyInjection\Loader\LoaderResolverInterface $resolver A LoaderResolverInterface instance
*/
public function __construct(LoaderResolverInterface $resolver)
{
$this->resolver = $resolver;
}

/**
* Loads a resource.
*
* @param mixed $resource A resource
*/
public function load($resource)
{
$loader = $this->resolver->resolve($resource);

if (false === $loader) {
throw new \InvalidArgumentException(sprintf('Unable to load the "%s" container resource.', is_string($resource) ? $resource : (is_object($resource) ? get_class($resource) : 'RESOURCE')));
}

return $loader->load($resource);
}

/**
* Returns true if this class supports the given resource.
*
* @param mixed $resource A resource
*
* @return Boolean true if this class supports the given resource, false otherwise
*/
public function supports($resource)
{
foreach ($this->resolver->getLoaders() as $loader) {
if ($loader->supports($resource)) {
return true;
}
}

return false;
}
}
17 changes: 17 additions & 0 deletions src/Symfony/Components/DependencyInjection/Loader/FileLoader.php
Expand Up @@ -22,6 +22,7 @@
*/
abstract class FileLoader extends Loader
{
protected $currentDir;
protected $paths;

/**
Expand All @@ -41,6 +42,22 @@ public function __construct(ContainerBuilder $container, $paths = array())
$this->paths = $paths;
}

/**
* Adds definitions and parameters from a resource.
*
* @param mixed $resource A Resource
*/
public function import($resource)
{
$loader = $this->resolve($resource);

if ($loader instanceof FileLoader && null !== $this->currentDir) {
$resource = $this->getAbsolutePath($resource, $this->currentDir);
}

$loader->load($resource);
}

/**
* @throws \InvalidArgumentException When provided file does not exist
*/
Expand Down
Expand Up @@ -47,4 +47,16 @@ public function load($file)
}
}
}

/**
* Returns true if this class supports the given resource.
*
* @param mixed $resource A resource
*
* @return Boolean true if this class supports the given resource, false otherwise
*/
public function supports($resource)
{
return is_string($resource) && 'ini' === pathinfo($resource, PATHINFO_EXTENSION);
}
}
56 changes: 56 additions & 0 deletions src/Symfony/Components/DependencyInjection/Loader/Loader.php
Expand Up @@ -23,6 +23,7 @@
abstract class Loader implements LoaderInterface
{
protected $container;
protected $resolver;

/**
* Constructor.
Expand All @@ -33,4 +34,59 @@ public function __construct(ContainerBuilder $container)
{
$this->container = $container;
}

/**
* Gets the loader resolver.
*
* @return \Symfony\Components\DependencyInjection\Loader\LoaderResolver A LoaderResolver instance
*/
public function getResolver()
{
return $this->resolver;
}

/**
* Sets the loader resolver.
*
* @param \Symfony\Components\DependencyInjection\Loader\LoaderResolver $resolver A LoaderResolver instance
*/
public function setResolver(LoaderResolver $resolver)
{
$this->resolver = $resolver;
}

/**
* Adds definitions and parameters from a resource.
*
* @param mixed $resource A Resource
*/
public function import($resource)
{
$this->resolve($resource)->load($resource);
}

/**
* Finds a loader able to load an imported resource.
*
* @param mixed $resource A Resource
*
* @return Symfony\Components\DependencyInjection\Loader\LoaderInterface A LoaderInterface instance
*
* @throws \InvalidArgumentException if no loader is found
*/
public function resolve($resource)
{
$loader = false;
if ($this->supports($resource)) {
$loader = $this;
} elseif (null !== $this->resolver) {
$loader = $this->resolver->resolve($resource);
}

if (false === $loader) {
throw new \InvalidArgumentException(sprintf('Unable to load the "%s" container resource.', is_string($resource) ? $resource : (is_object($resource) ? get_class($resource) : 'RESOURCE')));
}

return $loader;
}
}
Expand Up @@ -61,4 +61,27 @@ interface LoaderInterface
* @param mixed $resource The resource
*/
function load($resource);

/**
* Returns true if this class supports the given resource.
*
* @param mixed $resource A resource
*
* @return Boolean true if this class supports the given resource, false otherwise
*/
function supports($resource);

/**
* Gets the loader resolver.
*
* @return \Symfony\Components\Routing\Loader\LoaderResolver A LoaderResolver instance
*/
function getResolver();

/**
* Sets the loader resolver.
*
* @param \Symfony\Components\Routing\Loader\LoaderResolver $resolver A LoaderResolver instance
*/
function setResolver(LoaderResolver $resolver);
}
@@ -0,0 +1,76 @@
<?php

namespace Symfony\Components\DependencyInjection\Loader;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* LoaderResolver selects a loader for a given resource..
*
* @package Symfony
* @subpackage Components_DependencyInjection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class LoaderResolver implements LoaderResolverInterface
{
protected $loaders;

/**
* Constructor.
*
* @param \Symfony\Components\DependencyInjection\Loader\LoaderInterface[] $loaders An array of loaders
*/
public function __construct(array $loaders = array())
{
$this->loaders = array();
foreach ($loaders as $loader) {
$this->addLoader($loader);
}
}

/**
* Returns a loader able to load the resource.
*
* @param mixed $resource A resource
*
* @return Symfony\Components\DependencyInjection\Loader\LoaderInterface A LoaderInterface instance
*/
public function resolve($resource)
{
foreach ($this->loaders as $loader) {
if ($loader->supports($resource)) {
return $loader;
}
}

return false;
}

/**
* Sets a loader.
*
* @param \Symfony\Components\DependencyInjection\Loader\LoaderInterface $loader A LoaderInterface instance
*/
public function addLoader(LoaderInterface $loader)
{
$this->loaders[] = $loader;
$loader->setResolver($this);
}

/**
* Returns the registered loaders.
*
* @return \Symfony\Components\DependencyInjection\Loader\LoaderInterface[] A array of LoaderInterface instances
*/
public function getLoaders()
{
return $this->loaders;
}
}
@@ -0,0 +1,31 @@
<?php

namespace Symfony\Components\DependencyInjection\Loader;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* LoaderResolverInterface selects a loader for a given resource.
*
* @package Symfony
* @subpackage Components_DependencyInjection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface LoaderResolverInterface
{
/**
* Returns a loader able to load the resource.
*
* @param mixed $resource A resource
*
* @return Symfony\Components\DependencyInjection\Loader\LoaderInterface A LoaderInterface instance
*/
function resolve($resource);
}

0 comments on commit 60c6827

Please sign in to comment.