Skip to content

Commit 77581fb

Browse files
committed
Initialization
0 parents  commit 77581fb

7 files changed

+359
-0
lines changed

README.md

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Dependency Injection
2+
3+
## Installation
4+
5+
``` bash
6+
$ php composer.phar require yokai/dependency-injection
7+
```
8+
9+
## Compiler Pass
10+
11+
``` php
12+
<?php
13+
14+
namespace AppBundle;
15+
16+
use Yokai\DependencyInjection\CompilerPass\ArgumentRegisterTaggedServicesCompilerPass;
17+
use Yokai\DependencyInjection\CompilerPass\AdderRegisterTaggedServicesCompilerPass;
18+
use Yokai\DependencyInjection\CompilerPass\SetterRegisterTaggedServicesCompilerPass;
19+
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\HttpKernel\Bundle\Bundle;
21+
22+
class AppBundle extends Bundle
23+
{
24+
public function build(ContainerBuilder $container)
25+
{
26+
$container
27+
->addCompilerPass(
28+
new ArgumentRegisterTaggedServicesCompilerPass(
29+
'some_service_id',
30+
'some_tag_name',
31+
'An\Optional\Interface\To\Check',
32+
0
33+
)
34+
)
35+
->addCompilerPass(
36+
new AdderRegisterTaggedServicesCompilerPass(
37+
'some_service_id',
38+
'some_tag_name',
39+
'An\Optional\Interface\To\Check',
40+
'addDependency'
41+
)
42+
)
43+
->addCompilerPass(
44+
new SetterRegisterTaggedServicesCompilerPass(
45+
'some_service_id',
46+
'some_tag_name',
47+
'An\Optional\Interface\To\Check',
48+
'setDependencies'
49+
)
50+
)
51+
;
52+
}
53+
}
54+
```
55+
56+
### ArgumentRegisterTaggedServicesCompilerPass
57+
58+
This compiler pass will :
59+
60+
- check for the service (first argument) existence (throw `LogicException` if not)
61+
- find services tagged with tag (second argument)
62+
- if provided, check every service against an interface (third argument) (throw `LogicException` if not)
63+
- sort these references base on a `priority` attribute
64+
- replace an argument (fourth argument) of your service definition with the sorted references
65+
66+
67+
## AdderRegisterTaggedServicesCompilerPass
68+
69+
This compiler pass will :
70+
71+
- check for the service (first argument) existence (throw `LogicException` if not)
72+
- find services tagged with tag (second argument)
73+
- if provided, check every service against an interface (third argument) (throw `LogicException` if not)
74+
- sort these references base on a `priority` attribute
75+
- call a method (fourth argument) for each sorted references
76+
77+
78+
## SetterRegisterTaggedServicesCompilerPass
79+
80+
This compiler pass will :
81+
82+
- check for the service (first argument) existence (throw `LogicException` if not)
83+
- find services tagged with tag (second argument)
84+
- if provided, check every service against an interface (third argument) (throw `LogicException` if not)
85+
- sort these references base on a `priority` attribute
86+
- call a method (fourth argument) with all sorted references
87+
88+
89+
MIT License
90+
-----------
91+
92+
License can be found [here](https://github.com/yann-eugone/dependency-injection/blob/master/LICENSE).
93+
94+
95+
Authors
96+
-------
97+
98+
The bundle was originally created by [Yann Eugoné](https://github.com/yann-eugone).
99+
See the list of [contributors](https://github.com/yann-eugone/dependency-injection/contributors).

composer.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "yokai/dependency-injection",
3+
"type": "library",
4+
"description": "Provide util classes to manipulate Dependency Injection in Symfony",
5+
"keywords": ["dependency injection", "symfony"],
6+
"license": "MIT",
7+
"authors": [
8+
{
9+
"name": "Yann Eugoné",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"require": {
14+
"php": ">=5.5.9",
15+
"symfony/symfony": "~2.7|~3.0"
16+
},
17+
"require-dev": {
18+
"phpunit/phpunit": "~4.6"
19+
},
20+
"autoload": {
21+
"psr-4": { "Yokai\\DependencyInjection\\": "src" }
22+
},
23+
"autoload-dev": {
24+
"psr-4": { "Yokai\\DependencyInjection\\Tests\\": "tests" }
25+
},
26+
"extra": {
27+
"branch-alias": {
28+
"dev-master": "1.0-dev"
29+
}
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Yokai\DependencyInjection\CompilerPass;
4+
5+
use Symfony\Component\DependencyInjection\Definition;
6+
7+
/**
8+
* @author Yann Eugoné <[email protected]>
9+
*/
10+
class AdderRegisterTaggedServicesCompilerPass extends RegisterTaggedServicesCompilerPass
11+
{
12+
/**
13+
* @var string
14+
*/
15+
private $method;
16+
17+
/**
18+
* @inheritDoc
19+
*
20+
* @param string $index
21+
*/
22+
public function __construct($service, $tag, $interface, $index)
23+
{
24+
parent::__construct($service, $tag, $interface);
25+
26+
$this->method = $index;
27+
}
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
protected function registerServices(Definition $definition, array $references)
33+
{
34+
foreach ($references as $reference) {
35+
$definition->addMethodCall($this->method, [$reference]);
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Yokai\DependencyInjection\CompilerPass;
4+
5+
use Symfony\Component\DependencyInjection\Definition;
6+
7+
/**
8+
* @author Yann Eugoné <[email protected]>
9+
*/
10+
class ArgumentRegisterTaggedServicesCompilerPass extends RegisterTaggedServicesCompilerPass
11+
{
12+
/**
13+
* @var int
14+
*/
15+
private $index;
16+
17+
/**
18+
* @inheritDoc
19+
*
20+
* @param int $index
21+
*/
22+
public function __construct($service, $tag, $interface, $index)
23+
{
24+
parent::__construct($service, $tag, $interface);
25+
26+
$this->index = $index;
27+
}
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
protected function registerServices(Definition $definition, array $references)
33+
{
34+
$definition->replaceArgument($this->index, $references);
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
namespace Yokai\DependencyInjection\CompilerPass;
4+
5+
use LogicException;
6+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
use Symfony\Component\DependencyInjection\Definition;
9+
use Symfony\Component\DependencyInjection\Reference;
10+
11+
/**
12+
* @author Yann Eugoné <[email protected]>
13+
*/
14+
abstract class RegisterTaggedServicesCompilerPass implements CompilerPassInterface
15+
{
16+
/**
17+
* @var string
18+
*/
19+
private $service;
20+
21+
/**
22+
* @var string
23+
*/
24+
private $tag;
25+
26+
/**
27+
* @var null|string
28+
*/
29+
private $interface;
30+
31+
/**
32+
* @param string $service
33+
* @param string $tag
34+
* @param string|null $interface
35+
*/
36+
public function __construct($service, $tag, $interface = null)
37+
{
38+
$this->service = $service;
39+
$this->tag = $tag;
40+
$this->interface = $interface;
41+
}
42+
43+
/**
44+
* @inheritDoc
45+
*/
46+
public function process(ContainerBuilder $container)
47+
{
48+
if (!$container->hasDefinition($this->service) && !$container->hasAlias($this->service)) {
49+
throw new LogicException(
50+
sprintf(
51+
'The service "%s" is not registered',
52+
$this->service
53+
)
54+
);
55+
}
56+
57+
$services = [];
58+
59+
foreach ($container->findTaggedServiceIds($this->tag) as $serviceId => $tags) {
60+
61+
if (null !== $this->interface) {
62+
$serviceDefinition = $container->getDefinition($serviceId);
63+
if (!in_array($this->interface, class_implements($serviceDefinition->getClass()))) {
64+
throw new LogicException(
65+
sprintf(
66+
'The service "%s" must implement "%s" interface to be registered under the "%s" tag.',
67+
$serviceId,
68+
$this->interface,
69+
$this->tag
70+
)
71+
);
72+
}
73+
}
74+
75+
foreach ($tags as $attributes) {
76+
$priority = isset($attributes['priority']) ? $attributes['priority'] : 0;
77+
$services[$priority][] = new Reference($serviceId);
78+
}
79+
}
80+
81+
ksort($services);
82+
83+
if (count($services) > 0) {
84+
// Flatten the array
85+
$references = call_user_func_array('array_merge', $services);
86+
} else {
87+
$references = [];
88+
}
89+
90+
$definition = $container->findDefinition($this->service);
91+
92+
$this->registerServices($definition, $references);
93+
}
94+
95+
/**
96+
* @param Definition $definition
97+
* @param array $references
98+
*/
99+
abstract protected function registerServices(Definition $definition, array $references);
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Yokai\DependencyInjection\CompilerPass;
4+
5+
use Symfony\Component\DependencyInjection\Definition;
6+
7+
/**
8+
* @author Yann Eugoné <[email protected]>
9+
*/
10+
class SetterRegisterTaggedServicesCompilerPass extends RegisterTaggedServicesCompilerPass
11+
{
12+
/**
13+
* @var string
14+
*/
15+
private $method;
16+
17+
/**
18+
* @inheritDoc
19+
*
20+
* @param string $index
21+
*/
22+
public function __construct($service, $tag, $interface, $index)
23+
{
24+
parent::__construct($service, $tag, $interface);
25+
26+
$this->method = $index;
27+
}
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
protected function registerServices(Definition $definition, array $references)
33+
{
34+
$definition->addMethodCall($this->method, [$references]);
35+
}
36+
}

src/LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2016 Yann Eugoné
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

0 commit comments

Comments
 (0)