Skip to content

Commit

Permalink
Merge branch '3.4' into feature/OptionalParameters
Browse files Browse the repository at this point in the history
Conflicts:
	src/DI/Factory.php
	tests/IntegrationTests/DI/Fixtures/Class1.php
  • Loading branch information
mnapoli committed Sep 24, 2013
2 parents 2d02aa4 + 21f36e7 commit 1850df9
Show file tree
Hide file tree
Showing 22 changed files with 200 additions and 43 deletions.
5 changes: 5 additions & 0 deletions change-log.md
@@ -1,5 +1,10 @@
# Change log

## 3.4

* You can now define arrays of values (in YAML, PHP, …) [#106](https://github.com/mnapoli/PHP-DI/pull/106/)
* FIXED [#100](https://github.com/mnapoli/PHP-DI/issues/100): bug for lazy injection in constructors

## 3.3

Read the [news entry](news/03-php-di-3-3.md).
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -18,6 +18,6 @@
"doctrine/cache": "1.*",
"myclabs/php-enum": "1.*",
"symfony/yaml": "2.*",
"ocramius/proxy-manager": "0.3.*"
"ocramius/proxy-manager": "~0.3"
}
}
20 changes: 19 additions & 1 deletion doc/definition.md
Expand Up @@ -166,6 +166,12 @@ $container = new Container();
$container->set('db.host', 'localhost');
$container->set('db.port', 5000);

// Indexed non-empty array as value
$container->set('report.recipients', array(
'bob@acme.example.com',
'alice@acme.example.com'
));

// Direct mapping (not needed if you didn't disable Reflection)
$container->set('SomeClass');

Expand Down Expand Up @@ -230,8 +236,14 @@ return [
'db.host' => 'localhost',
'db.port' => 5000,

// Indexed non-empty array as value
'report.recipients' => [
'bob@acme.example.com',
'alice@acme.example.com'
],

// Direct mapping (not needed if you didn't disable Reflection)
'SomeClass' => array(),
'SomeClass' => [],

// This is not recommended: will instantiate the class even when not used, prevents caching
'SomeOtherClass' => new SomeOtherClass(1, "hello"),
Expand Down Expand Up @@ -298,6 +310,11 @@ Example of a `config/di.yml` file:
db.host: localhost
db.port: 5000

# Indexed non-empty array as value
report.recipients:
- bob@acme.example.com
- alice@acme.example.com

# Direct mapping (not needed if you didn't disable Reflection)
SomeClass:

Expand Down Expand Up @@ -330,3 +347,4 @@ My\Interface:
myNamedInstance:
class: My\Class
```

2 changes: 1 addition & 1 deletion doc/getting-started.md
Expand Up @@ -12,7 +12,7 @@ Create a file named `composer.json` in your project root:
```json
{
"require": {
"mnapoli/php-di": "3.3.*"
"mnapoli/php-di": "~3.4"
}
}
```
Expand Down
21 changes: 18 additions & 3 deletions doc/performances.md
Expand Up @@ -12,11 +12,13 @@ PHP-DI offers an easy and complete solution to put those data into a cache based
### Setup

```php
$container->setDefinitionCache(new Doctrine\Common\Cache\ArrayCache());
$container->setDefinitionCache(new Doctrine\Common\Cache\ApcCache());
```

Heads up: It is recommended not to use a cache in a development environment, else changes you make to the definitions (annotations, configuration files, etc.) may not be taken into account.

Heads up: do not use a cache in a development environment, else changes you make to the definitions
(annotations, configuration files, etc.) may not be taken into account.
The only cache you should use in development is the `ArrayCache` because it doesn't persist data between requests.
Of course, do not use this one in production.

### Cache types

Expand All @@ -35,3 +37,16 @@ The cache implementation is provided by Doctrine (because it works very well) an

Read the [Doctrine documentation](http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/caching.html)
for more details.

### Cache prefixes

If you run the same application twice on the same machine, both installs will use the same cache, and there might be conflicts.

To avoid this situation, you should use a cache "prefix": each installation of your app has a unique ID, and this ID is used to prefix cache keys
to avoid collisions.

```php
$cache = new Doctrine\Common\Cache\ApcCache();
$cache->setNamespace('MyApplication');
$container->setDefinitionCache($cache);
```
19 changes: 17 additions & 2 deletions src/DI/ContainerBuilder.php
Expand Up @@ -18,7 +18,7 @@
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;

/**
* Helper to create a Container
* Fluent helper to create a Container
*
* @since 3.2
* @author Matthieu Napoli <matthieu@mnapoli.fr>
Expand Down Expand Up @@ -102,52 +102,62 @@ public function build()
*
* By default, enabled
* @param boolean $bool
* @return ContainerBuilder
*/
public function useReflection($bool)
{
$this->useReflection = $bool;
return $this;
}

/**
* Enable or disable the use of annotations
*
* By default, enabled
* @param boolean $bool
* @param $bool
* @return ContainerBuilder
*/
public function useAnnotations($bool)
{
$this->useAnnotations = $bool;
return $this;
}

/**
* Enables/disables the validation of the definitions
*
* By default, disabled
* @param bool $bool
* @return ContainerBuilder
*/
public function setDefinitionsValidation($bool)
{
$this->definitionsValidation = $bool;
return $this;
}

/**
* Enables the use of a cache for the definitions
*
* @param Cache $cache Cache backend to use
* @return ContainerBuilder
*/
public function setDefinitionCache(Cache $cache)
{
$this->cache = $cache;
return $this;
}

/**
* Add definitions contained in a file
*
* @param DefinitionFileLoader $definitionFileLoader
* @return ContainerBuilder
*/
public function addDefinitionsFromFile(DefinitionFileLoader $definitionFileLoader)
{
$this->fileLoaders[] = $definitionFileLoader;
return $this;
}

/**
Expand All @@ -158,6 +168,9 @@ public function addDefinitionsFromFile(DefinitionFileLoader $definitionFileLoade
*
* @param boolean $writeToFile If true, write the proxies to disk to improve performances
* @param string|null $proxyDirectory Directory where to write the proxies
* @return ContainerBuilder
*
* @throws InvalidArgumentException when writeToFile is set to true and the proxy directory is null
*/
public function writeProxiesToFile($writeToFile, $proxyDirectory = null)
{
Expand All @@ -167,6 +180,8 @@ public function writeProxiesToFile($writeToFile, $proxyDirectory = null)
throw new InvalidArgumentException("The proxy directory must be specified if you want to write proxies on disk");
}
$this->proxyDirectory = $proxyDirectory;

return $this;
}

}
3 changes: 2 additions & 1 deletion src/DI/Definition/FileLoader/DefinitionFileLoader.php
Expand Up @@ -33,11 +33,12 @@ abstract class DefinitionFileLoader
*/
public function __construct($fileName)
{
if (!file_exists($fileName)) {
if (!is_file($fileName)) {
throw new FileNotFoundException("The definition file '$fileName' has not been found");
} elseif (!is_readable($fileName)) {
throw new ParseException("The definition file '$fileName' is not readable");
}

$this->definitionFile = $fileName;
}

Expand Down
2 changes: 2 additions & 0 deletions src/DI/Definition/FileLoader/XmlDefinitionFileLoader.php
Expand Up @@ -15,6 +15,8 @@
* XmlDefinitionFileLoader loads XML files definitions.
*
* @author Domenic Muskulus <domenic@muskulus.eu>
*
* @deprecated XML definitions are not maintained and documented, will be removed
*/
class XmlDefinitionFileLoader extends DefinitionFileLoader
{
Expand Down
35 changes: 20 additions & 15 deletions src/DI/Definition/Helper/ClassDefinitionHelper.php
Expand Up @@ -78,11 +78,7 @@ public function withProperty($propertyName, $entryToInject, $lazy = false)
*/
public function withConstructor(array $params)
{
$paramInjections = array();
foreach ($params as $key => $param) {
$paramInjections[] = new ParameterInjection($key, $param);
}
$this->classDefinition->setConstructorInjection(new MethodInjection('__construct', $paramInjections));
$this->classDefinition->setConstructorInjection($this->createMethodInjection('__construct', $params));
return $this;
}

Expand All @@ -92,6 +88,24 @@ public function withConstructor(array $params)
* @return $this
*/
public function withMethod($methodName, array $params)
{
$this->classDefinition->addMethodInjection($this->createMethodInjection($methodName, $params));
return $this;
}

/**
* @return ClassDefinition
*/
public function getDefinition()
{
return $this->classDefinition;
}

/**
* @param string[] $params Parameters for the method: array of container entries names
* @return MethodInjection
*/
private function createMethodInjection($methodName, array $params)
{
$paramInjections = array();

Expand All @@ -108,16 +122,7 @@ public function withMethod($methodName, array $params)
$paramInjections[] = $parameterInjection;
}

$this->classDefinition->addMethodInjection(new MethodInjection($methodName, $paramInjections));
return $this;
}

/**
* @return ClassDefinition
*/
public function getDefinition()
{
return $this->classDefinition;
return new MethodInjection($methodName, $paramInjections);
}

}
3 changes: 1 addition & 2 deletions src/DI/Definition/Source/ArrayDefinitionSource.php
Expand Up @@ -54,7 +54,7 @@ public function getDefinition($name)
}

// Value definition
if (!is_array($arrayDefinition)) {
if (!is_array($arrayDefinition) || ($arrayDefinition && array_values($arrayDefinition) === $arrayDefinition)) {
return new ValueDefinition($name, $arrayDefinition);
}

Expand Down Expand Up @@ -281,5 +281,4 @@ private function mergeWithParents($name, ClassDefinition $definition)
}
}
}

}
7 changes: 5 additions & 2 deletions src/DI/Factory.php
Expand Up @@ -128,8 +128,11 @@ private function injectConstructor(ReflectionClass $classReflection, MethodInjec
. "' of the constructor of '{$classReflection->name}' has no type defined or guessable");
}

// TODO handle lazy injections!
$args[] = $this->container->get($entryName);
if ($parameterInjection->isLazy()) {
$args[] = $this->container->get($entryName, true);
} else {
$args[] = $this->container->get($entryName);
}
}

return $classReflection->newInstanceArgs($args);
Expand Down
12 changes: 8 additions & 4 deletions tests/IntegrationTests/DI/Fixtures/Class1.php
Expand Up @@ -49,6 +49,7 @@ class Class1

public $constructorParam1;
public $constructorParam2;
public $constructorParam3;

public $method1Param1;

Expand All @@ -60,14 +61,17 @@ class Class1
public $method4Param1;

/**
* @param Class2 $param1
* @param Interface1 $param2
* @Inject({"param3" = {"lazy" = true}})
* @param Class2 $param1
* @param Interface1 $param2
* @param LazyDependency $param3
* @throws \Exception
*/
public function __construct(Class2 $param1, Interface1 $param2, $optional = true)
public function __construct(Class2 $param1, Interface1 $param2, LazyDependency $param3, $optional = true)
{
$this->constructorParam1 = $param1;
$this->constructorParam2 = $param2;
$this->constructorParam3 = $param3;

if ($optional !== true) {
throw new \Exception("Expected optional parameter to not be defined");
Expand Down Expand Up @@ -109,7 +113,7 @@ public function method3($param1, $param2)

/**
* @Inject({"param1" = {"lazy" = true}})
* @param string $param1
* @param LazyDependency $param1
*/
public function method4(LazyDependency $param1)
{
Expand Down
4 changes: 4 additions & 0 deletions tests/IntegrationTests/DI/Fixtures/definitions.php
Expand Up @@ -19,6 +19,10 @@
'constructor' => array(
'param1' => 'IntegrationTests\DI\Fixtures\Class2',
'param2' => 'IntegrationTests\DI\Fixtures\Interface1',
'param3' => array(
'name' => 'IntegrationTests\DI\Fixtures\LazyDependency',
'lazy' => true,
),
),
'methods' => array(
'method1' => 'IntegrationTests\DI\Fixtures\Class2',
Expand Down
3 changes: 3 additions & 0 deletions tests/IntegrationTests/DI/Fixtures/definitions.yml
Expand Up @@ -15,6 +15,9 @@ IntegrationTests\DI\Fixtures\Class1:
constructor:
param1: IntegrationTests\DI\Fixtures\Class2
param2: IntegrationTests\DI\Fixtures\Interface1
param3:
name: IntegrationTests\DI\Fixtures\LazyDependency
lazy: true
methods:
method1: IntegrationTests\DI\Fixtures\Class2
method2: [IntegrationTests\DI\Fixtures\Interface1]
Expand Down

0 comments on commit 1850df9

Please sign in to comment.