11/07/2019 - SYMFONY
Bu örneğimizde bir tane vendor paketi oluşturacağız ve varsayılan değerlere/argümanlara sahip olan bir servis tanımına sahip olacak. Ardından, ana uygulamalardan gelen değişkenlerle, varsayılan değerleri/argümanları değiştireceğiz.
.
├── composer.json
└── src
├── BuddyBundle.php
├── DependencyInjection
│ ├── BuddyExtension.php
│ └── Configuration.php
├── Resources
│ └── config
│ └── services.yaml
├── Service
│ ├── PrinterInterface.php
│ ├── ScreenService.php
│ └── TerminalService.php
└── Utility
└── HelloUtility.php
{
"name": "Inanzzz/buddy",
"type": "symfony-bundle",
"description": "Buddy up",
"license": "MIT",
"require": {
"php": "^7.2",
"symfony/config": "^4.2",
"symfony/dependency-injection": "^4.2"
},
"autoload": {
"psr-4": {
"Inanzzz\\Buddy\\": "src/"
}
},
"config": {
"sort-packages": true
},
"prefer-stable": true,
"minimum-stability": "stable"
}
declare(strict_types=1);
namespace Inanzzz\Buddy;
use Inanzzz\Buddy\DependencyInjection\BuddyExtension;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class BuddyBundle extends Bundle
{
public function getContainerExtension()
{
if (null === $this->extension) {
$this->extension = new BuddyExtension();
}
return $this->extension;
}
}
declare(strict_types=1);
namespace Inanzzz\Buddy\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class BuddyExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yaml');
$this->setServices($container, $config);
}
public function getAlias()
{
return Configuration::CONFIG_ROOT;
}
private function setServices(ContainerBuilder $container, array $config): void
{
// Fetch existing service definition and override its class with either:
// - the default value coming from 'Configuration.php' file
// or
// - the specific value coming from the parent application.
$classService = $container->getDefinition(sprintf('%s.service.%s',
Configuration::CONFIG_CHILD,
Configuration::CONFIG_PRINTER
));
$classService->setClass($config[Configuration::CONFIG_CHILD][Configuration::CONFIG_PRINTER]);
// Fetch existing service definition and override its arguments one by one with either:
// - the default values coming from 'Configuration.php' file
// or
// - the specific values coming from the parent application.
$argumentService = $container->getDefinition('Inanzzz\Buddy\Utility\HelloUtility');
$argumentService->setArgument(
sprintf('$%s', Configuration::CONFIG_MESSAGE),
$config[Configuration::CONFIG_CHILD][Configuration::CONFIG_MESSAGE]
);
$argumentService->setArgument(
sprintf('$%s', Configuration::CONFIG_PRINTER),
$classService
);
}
}
declare(strict_types=1);
namespace Inanzzz\Buddy\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public const CONFIG_ROOT = 'inanzzz';
public const CONFIG_CHILD = 'buddy';
public const CONFIG_MESSAGE = 'message';
public const CONFIG_PRINTER = 'printer';
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder(self::CONFIG_ROOT);
$treeBuilder->getRootNode()
->children()
->arrayNode(self::CONFIG_CHILD)
->addDefaultsIfNotSet()
->children()
->scalarNode(self::CONFIG_MESSAGE)
->cannotBeEmpty()
->defaultValue('inanzzz')
->end()
->scalarNode(self::CONFIG_PRINTER)
->cannotBeEmpty()
->defaultValue('Inanzzz\Buddy\Service\TerminalService')
->end()
->end()
->end()
->end();
return $treeBuilder;
}
}
services:
# SERVICE
buddy.service.printer:
class: ~
# UTILITY
Inanzzz\Buddy\Utility\HelloUtility:
arguments:
$printer: ~
$message: ~
declare(strict_types=1);
namespace Inanzzz\Buddy\Service;
interface PrinterInterface
{
public function print(string $message): void;
}
declare(strict_types=1);
namespace Inanzzz\Buddy\Service;
class ScreenService implements PrinterInterface
{
public function print(string $message): void
{
echo sprintf('Printing %s to screen!', $message);
}
}
declare(strict_types=1);
namespace Inanzzz\Buddy\Service;
class TerminalService implements PrinterInterface
{
public function print(string $message): void
{
echo sprintf('Printing %s to terminal!', $message);
}
}
declare(strict_types=1);
namespace Inanzzz\Buddy\Utility;
use Inanzzz\Buddy\Service\PrinterInterface;
class HelloUtility
{
private $printer;
private $message;
public function __construct(
PrinterInterface $printer,
string $message
) {
$this->printer = $printer;
$this->message = $message;
}
public function handle(): void
{
$this->printer->print($this->message);
}
}
Ana uygulamanın her hangi bir servisine HelloUtility
classı enjekte ettiğinizi varsayalım. Yaptığınız konfigürasyona göre aşağıdaki çıktıları alacaksınız.
inanzzz:
buddy:
printer: 'Inanzzz\Buddy\Service\ScreenService'
// Printing inanzzz to screen!
inanzzz:
buddy:
message: 'moon'
// Printing moon to terminal!
inanzzz:
buddy:
printer: 'Inanzzz\Buddy\Service\ScreenService'
message: 'mama'
// Printing mama to screen!
inanzzz:
buddy:
inanzzz:
// Printing inanzzz to terminal!
inanzzz:
buddy:
printer: 'Some\Parent\Servie\That\Implements\PrinterInterface'
message: 'something'
// Printing something to parent printer!