Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Nette framework - How to compile an extensible di container

Nette framework - How to compile an extensible di container

Everything you should know, before you start writing your own (DI compiler) extensions for Nette Framework.

Filip Procházka

December 21, 2015
Tweet

More Decks by Filip Procházka

Other Decks in Technology

Transcript

  1. Co si povíme? - Ujasníme si pojmy - Koukneme jak

    funguje DI v Nette - Ukážeme si jak napsat rozšíření
  2. app/bootstrap.php $c = new Nette\Configurator; $c->setTempDirectory(__DIR__ . '/../temp'); $c->addConfig(__DIR__ .

    '/config/config.neon'); $c->addConfig(__DIR__ . '/config/config.local.neon'); $container = $configurator->createContainer();
  3. ->createContainer() Zkusí jestli už zkompilovaný container existuje - pokud ano,

    tak vytvoří instanci. - pokud ne, tak zkompiluje container a vytvoří instanci
  4. Kompilace pohledem z dálky - nakonfiguruje se ContainerBuilder - Nette

    vygeneruje PHP třídu - uloží do tempu - profit
  5. Co se vygeneruje? class SystemContainer extends Nette\DI\Container { protected $meta

    = array( 'types' => array(), 'services' => array(), 'tags' => array() ); public function __construct() { parent::__construct(array(/* parameters */)); }
  6. Co se vygeneruje? class SystemContainer extends Nette\DI\Container { public function

    createServiceApplication() { $service = new Nette\Application\Application( $this->getService('nette.presenterFactory'), ... ); $service->catchExceptions = FALSE; $service->errorPresenter = 'Front:Error'; return $service; }
  7. Kompilace DI Containeru - načte configy a všechny je spojí

    do pole - expandne parametry parameters: imageDir: %wwwDir%/images
  8. Kompilace DI Containeru - zavolá všechna rozšíření - Nette samo

    sebe konfiguruje rozšířenímy $ext->loadConfiguration()
  9. Každé rozšíření - pracuje s ContainerBuilder - dědí od Nette\DI\CompilerExtension

    - má “dynamické” jméno - má vlastní sekci v configu
  10. ContainerBuilder class ContainerBuilder { /** @return ServiceDefinition */ function addDefinition($name,

    $definition = NULL); /** @return ServiceDefinition */ function getDefinition($name); /** @return ServiceDefinition[] */ function getDefinitions(); function removeDefinition($name);
  11. ContainerBuilder class ContainerBuilder { /** @return string service name or

    NULL */ function getByType($class); /** @return string[] */ function findByType($class, $autowired = TRUE); /** @return array of [service name => tag attributes] */ function findByTag($tag);
  12. ContainerBuilder class ContainerBuilder { public $parameters = array(); function expand($value);

    function addExcludedClasses(array $classes); function addDependency($file); /** @return Nette\PhpGenerator\PhpLiteral */ static function literal($phpCode);
  13. ServiceDefinition class ServiceDefinition extends Nette\Object { public $class; public $factory;

    public $setup = array(); public $parameters = array(); public $tags = array(); public $autowired = TRUE; public $dynamic = FALSE; public $implement; public $implementType;
  14. Extension points of extensions - loadConfiguration() - pouze na zpracování

    configu a přidávání služeb - beforeCompiler() - modifikace existujících služeb, nepřidávat nové! - afterCompile() - modifikace vygenerovaného kódu
  15. afterCompile($class) use Nette\PhpGenerator as Code; public function afterCompile(Code\ClassType $class) {

    $config = $this->getConfig(); $initialize = $class->methods['initialize']; $initialize->addBody('date_default_timezone_set(?);', array($config['date.timezone']));
  16. Závislosti rozšíření - například BlogExtension, který potřebuje OrmExtension - vyřešilo

    se to změnou přístupu - dva přístupy - ask (starý) - tell (lepší)