Stephan Hochdörfer // 18.04.2017
<?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="dependency" class="\My\Dependency"> </service> <service id="manager" class="\My\Manager"> <call method="setDependency"> <argument type="service" id="dependency" /> </call> </service> </services> </container>
<?php use Symfony\Component\DependencyInjection\Reference; // ... $container ->register('dependency', \My\Dependency::class); $container ->register('manager', \My\Manager::class) ->addMethodCall('setDependency', array(new Reference('dependency')));
<?php $manager = new \My\Manager(); $manager->setDependency(new \My\Dependency());
<?php $container = new \Pimple\Container(); $container['database'] = function ($c) { return new Database('mysql://user:secret@localhost/mydb'); }; $container['productService'] = function ($c) { return new ProductService($c['database']); };
$ composer.phar require bitexpert/disco
<?php require __DIR__ .'/vendor/autoload.php'; use bitExpert\Disco\AnnotationBeanFactory; use bitExpert\Disco\BeanFactoryRegistry; $beanFactory = new AnnotationBeanFactory(Config::class); BeanFactoryRegistry::register($beanFactory);
$beanFactory->get('productService');
$beanFactory->has('productService');
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ public function productService() : ProductService { $db = new Database('mysql://user:secret@localhost/mydb'); return new ProductService($db); } }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php require __DIR__ .'/vendor/autoload.php'; use bitExpert\Disco\AnnotationBeanFactory; use bitExpert\Disco\BeanFactoryRegistry; $beanFactory = new AnnotationBeanFactory(\Demo\Config::class); BeanFactoryRegistry::register($beanFactory); var_dump($beanFactory->has('database')); var_dump($beanFactory->has('productService'));
bool(false) bool(true)
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ public function productService1() : ProductService { return $this->productServiceFactory( new Database('mysql://user:secret@localhost/mydb1')); } /** @Bean */ public function productService2() : ProductService { return $this->productServiceFactory( new Database('mysql://user:secret@localhost/mydb2')); }
private function productServiceFactory(Database $db) : ProductService { return new ProductService($db); } }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; use bitExpert\Disco\Annotations\Parameter; use bitExpert\Disco\Annotations\Parameters; /** @Configuration */ class Config { /** * @Bean * @Parameters({ * @Parameter({"name" = "db.dsn"}) * }) */ protected function database($dsn = '') : Database { return new Database($dsn); } // [...] }
<?php $config = [ 'db' => [ 'dsn' => 'mysql://user:secret@localhost/mydb' ] ]; $beanFactory = new AnnotationBeanFactory(Config::class, $config); BeanFactoryRegistry::register($beanFactory);
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; use bitExpert\Disco\Annotations\Parameter; use bitExpert\Disco\Annotations\Parameters; /** @Configuration */ class Config { /** * @Bean * @Parameters({ * @Parameter({"name" = "db.dsn", "default" = "mysql://..."}) * }) */ protected function database($dsn = '') : Database { return new Database($dsn); } // [...] }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; use bitExpert\Disco\Annotations\Parameter; use bitExpert\Disco\Annotations\Parameters; /** @Configuration */ class Config { // [...] /** @Bean */ public function productService() : ProductService { // no need to pass parameters to the database method! return new ProductService($this->database()); } }
$ composer.phar require vlucas/phpdotenv
DB_DSN="mysql://user:secret@localhost/mydb"
<?php require __DIR__ .'/vendor/autoload.php'; use bitExpert\Disco\AnnotationBeanFactory; use bitExpert\Disco\BeanFactoryRegistry; $dotenv = new Dotenv\Dotenv(__DIR__); $dotenv->load(); $beanFactory = new AnnotationBeanFactory(Config::class, $_ENV); BeanFactoryRegistry::register($beanFactory);
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"singleton" = true}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php var_dump($instance = $beanFactory->get('productService')); var_dump($instance2 = $beanFactory->get('productService'));
object(Demo\ProductService)#9 (0) { } object(Demo\ProductService)#9 (0) { }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"singleton" = false}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php var_dump($instance = $beanFactory->get('productService')); var_dump($instance2 = $beanFactory->get('productService'));
object(Demo\ProductService)#9 (0) { } object(Demo\ProductService)#11 (0) { }
<?php namespace Demo; use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"lazy" = false}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php var_dump($instance = $beanFactory->get('productService'));
object(Demo\ProductService)#9 (0) { }
<?php namespace Demo; use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"lazy" = true}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php var_dump($instance = $beanFactory->get('productService'));
object(ProxyManagerGeneratedProxy\__PM__\ProductService\Gen1d5)#143 (3) { }
<?php require_once __DIR__ . '/vendor/autoload.php'; use ProxyManager\Factory\LazyLoadingValueHolderFactory; use ProxyManager\Proxy\LazyLoadingInterface; $factory = new LazyLoadingValueHolderFactory(); $initializer = function (& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) { $initializer = null; $wrappedObject = new ProductService(); return true; }; $proxy = $factory->createProxy('ProductService', $initializer);
<?php namespace Demo; use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"scope" = "request"}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php namespace Demo; use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"scope" = "session"}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php require __DIR__ .'/vendor/autoload.php'; use bitExpert\Disco\AnnotationBeanFactory; use bitExpert\Disco\BeanFactoryRegistry; $config = new \bitExpert\Disco\BeanFactoryConfiguration(sys_get_temp_dir()); $beanFactory = new AnnotationBeanFactory(Config::class, [], $config); BeanFactoryRegistry::register($beanFactory);
$beanStore = serialize($config->getBeanStore());
<?php require __DIR__ .'/vendor/autoload.php'; use bitExpert\Disco\AnnotationBeanFactory; use bitExpert\Disco\BeanFactoryRegistry; $beanStore = unserialize($beanStore); $config = new \bitExpert\Disco\BeanFactoryConfiguration( sys_get_temp_dir() ); $config->setBeanStore($beanStore); $beanFactory = new AnnotationBeanFactory(Config::class, [], $config); BeanFactoryRegistry::register($beanFactory);
<?php namespace Demo; use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } /** @Bean({"alias" = "\Identifier\With\Namespace"}) */ public function productService() : ProductService { return new ProductService($this->database()); } }
<?php var_dump($instance = $beanFactory->get('productService')); var_dump($instance2 = $beanFactory->get('\Identifier\With\Namespace'));
object(Demo\ProductService)#9 (0) { } object(Demo\ProductService)#9 (0) { }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @Bean({"alias" = "\My\Db"}) */ protected function database() : Database { return new Database('mysql://user:secret@localhost/mydb'); } }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class BeanConfiguration { /** * @Bean */ public function disco() : string { return 'Disco rocks!'; } }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; use bitExpert\Disco\Annotations\Parameter; use bitExpert\Disco\Annotations\Parameters; /** @Configuration */ class BeanConfiguration { /** * @Bean * @Parameters({ * @Parameter({"name" = "disco"}) * }) */ public function disco($disco = '') : string { return $disco; } }
<?php use bitExpert\Disco\Annotations\Bean; trait ProductSlice { /** @Bean */ public function productService() : ProductService { $db = new Database('mysql://user:secret@localhost/mydb'); return new ProductService($db); } }
<?php use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class BeanConfiguration { use ProductSlice; }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class BeanConfiguration { use ProductSlice; /** @Bean */ public function productService() : ProductService { return new CustomProductService(); } }
/home/shochdoerfer/Workspace/disco-demo |-src |---Demo |-----Config.php |-----SliceA |-------SliceAConfigTrait.php |-----SliceB |-------SliceBConfigTrait.php |-----SliceC |-------SliceCConfigTrait.php
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\BeanPostProcessor; use bitExpert\Disco\Annotations\Configuration; /** @Configuration */ class Config { /** @BeanPostProcessor */ public function charset() : DatabaseBeanCharSetPostProcessor { return new DatabaseBeanCharSetPostProcessor(); } }
<?php use bitExpert\Disco\Annotations\Bean; use bitExpert\Disco\Annotations\BeanPostProcessor; use bitExpert\Disco\Annotations\Configuration; use bitExpert\Disco\Annotations\Parameter; use bitExpert\Disco\Annotations\Parameters; /** @Configuration */ class Config { /** * @BeanPostProcessor * @Parameters({ * @Parameter({"name" = "db.charset"}) * }) */ public function charset($cst = '') : DatabaseBeanCharSetPostProcessor { return new DatabaseBeanCharSetPostProcessor($cst); } }
<?php use bitExpert\Disco\BeanPostProcessor; class DatabaseBeanCharSetPostProcessor implements BeanPostProcessor { protected $charset; public function __construct($charset) { $this->charset = $charset } public function postProcess($bean, $beanName) { if ($bean instanceof Database) { $bean->setCharset($this->charset); } } }
<?php $projectTmpDir = '/some/path/on/the/server/'; $config = new \bitExpert\Disco\BeanFactoryConfiguration($projectTmpDir); $config->setProxyAutoloader( new \ProxyManager\Autoloader\Autoloader( new \ProxyManager\FileLocator\FileLocator($projectTmpDir), new \ProxyManager\Inflector\ClassNameInflector('Disco') ) ); $beanFactory = new \bitExpert\Disco\AnnotationBeanFactory(Config::class, [],$config); BeanFactoryRegistry::register($beanFactory);
sitepoint.com: A Fresh Look at Dependency Injection
php[architect]: Your Dependency Injection Needs a Disco