Created
December 20, 2020 20:03
-
-
Save Punk-UnDeaD/8882e74c5dd2ba66d1dc9ca038cd2800 to your computer and use it in GitHub Desktop.
AutoInject
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Container; | |
#[\Attribute(\Attribute::TARGET_PROPERTY)] | |
class AutoInject | |
{ | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Container; | |
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | |
use Symfony\Component\DependencyInjection\ContainerBuilder; | |
use Symfony\Component\DependencyInjection\Reference; | |
class AutoInjectorCompilerPass implements CompilerPassInterface | |
{ | |
public function process(ContainerBuilder $container) | |
{ | |
foreach ($container->getDefinitions() as $name => $definition) { | |
$class = $definition->getClass() ?? $name; | |
if (in_array($class, get_declared_classes()) | |
&& is_subclass_of($class, AutoInjectorInterface::class) | |
) { | |
$reflection = new \ReflectionClass($class); | |
$properties = $reflection->getProperties(); | |
foreach ($properties as $property) { | |
if ($attributes = $property->getAttributes(AutoInject::class)) { | |
$definition->addMethodCall( | |
'inject', | |
[$property->getName(), new Reference($property->getType()->getName())] | |
); | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Container; | |
interface AutoInjectorInterface | |
{ | |
public function inject(string $field, $service); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Container; | |
trait AutoInjectorTrait | |
{ | |
public function inject(string $field, $service) | |
{ | |
$this->$field = $service; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
при компиляции контейнера, если класс реализует интерфейс, то если у свойства есть аттрибут, в определение сервиса добавляется вызов с именем свойства и подходящим сервисом из контейнера