SlideShare une entreprise Scribd logo
1  sur  45
Télécharger pour lire hors ligne
Nette Framework
How to compile an extensible DI Container
@ProchazkaFilip
Co si povíme?
- Ujasníme si pojmy
- Koukneme jak funguje DI v Nette
- Ukážeme si jak napsat rozšíření
Pojmy
- Dependency Injection Container
- služba
- rozšíření
- neon
Jak to funguje v Nette?
Ale než postoupíme,
je všechno jasné?
DIContainer
class Container
{
function getParameters();
function addService($name, $service);
function getService($name);
function getByType($class, $need = TRUE);
Jak se to používá?
$container = new Container();
$container->addService('app, new Application);
$app = $container->getService('app');
To asi nebude ideální
Vytvořit instance 500 tříd na každý request?
To nechceš.
Řešením
je kompilace DIC!
app/bootstrap.php
$c = new NetteConfigurator;
$c->setTempDirectory(__DIR__ . '/../temp');
$c->addConfig(__DIR__ . '/config/config.neon');
$c->addConfig(__DIR__ . '/config/config.local.neon');
$container = $configurator->createContainer();
new NetteConfigurator
- vyřeší výchozí parametry
->setTempDirectory()
- nastaví temp složku
- nastaví parametr tempDir
->addConfig()
- přidá neon/ini/php config
->createContainer()
->createContainer()
Zkusí jestli už zkompilovaný container existuje
- pokud ano, tak vytvoří instanci.
- pokud ne, tak zkompiluje container
a vytvoří instanci
Kompilace pohledem z dálky
- nakonfiguruje se ContainerBuilder
- Nette vygeneruje PHP třídu
- uloží do tempu
- profit
Co se vygeneruje?
class SystemContainer extends NetteDIContainer {
protected $meta = array(
'types' => array(),
'services' => array(),
'tags' => array()
);
public function __construct() {
parent::__construct(array(/* parameters */));
}
Co se vygeneruje?
class SystemContainer extends NetteDIContainer {
public function createServiceApplication()
{
$service = new NetteApplicationApplication(
$this->getService('nette.presenterFactory'), ...
);
$service->catchExceptions = FALSE;
$service->errorPresenter = 'Front:Error';
return $service;
}
Jak se to používá?
$app = $container
->getService('application');
use NetteApplicationApplication;
$app = $container
->getByType(Application::class);
Proces kompilace
Ale než postoupíme,
je všechno jasné?
Kompilace DI Containeru
- načte configy a všechny je spojí do pole
- expandne parametry
parameters:
imageDir: %wwwDir%/images
Kompilace DI Containeru
- zavolá všechna rozšíření
- Nette samo sebe konfiguruje rozšířenímy
$ext->loadConfiguration()
Kompilace DI Containeru
- projde služby z configu
services:
- AppUserManager
Kompilace DI Containeru
- zavolá všechna rozšíření
$ext->beforeCompile()
Kompilace DI Containeru
- autowiring
- vygeneruje PHP třídu SystemContainer
Kompilace DI Containeru
- zavolá všechna rozšíření
$ext->afterCompile($class)
Kompilace DI Containeru
- uložit do tempu
- profit
Jak fungují rozšíření
Ale než postoupíme,
je všechno jasné?
Každé rozšíření
- pracuje s ContainerBuilder
- dědí od NetteDICompilerExtension
- má “dynamické” jméno
- má vlastní sekci v configu
ContainerBuilder
class ContainerBuilder
{
/** @return ServiceDefinition */
function addDefinition($name, $definition = NULL);
/** @return ServiceDefinition */
function getDefinition($name);
/** @return ServiceDefinition[] */
function getDefinitions();
function removeDefinition($name);
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);
ContainerBuilder
class ContainerBuilder
{
public $parameters = array();
function expand($value);
function addExcludedClasses(array $classes);
function addDependency($file);
/** @return NettePhpGeneratorPhpLiteral */
static function literal($phpCode);
ServiceDefinition
class ServiceDefinition extends NetteObject {
public $class;
public $factory;
public $setup = array();
public $parameters = array();
public $tags = array();
public $autowired = TRUE;
public $dynamic = FALSE;
public $implement;
public $implementType;
Registrace rozšíření
extensions:
doctrine: KdybyDoctrineDIOrmExtension
doctrine:
host: 127.0.0.1
user: root
password: heslo
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
Rozumné výchozí hodnoty
public $defaults = array(
'catchExceptions' => "%productionMode%",
);
loadConfiguration()
public function loadConfiguration()
{
$builder = $this->getContainerBuilder();
$config = $this->getConfig($this->defaults);
// ...
loadConfiguration()
Validators::assertField($config,
'catchExceptions', 'bool');
$builder
->addDefinition($this->prefix('application'))
->setClass('NetteApplicationApplication')
->addSetup('$catchExceptions',
array($config['catchExceptions']));
beforeCompile()
public function beforeCompile()
{
$builder = $this->getContainerBuilder();
// ...
beforeCompile()
$manager = $builder->getDefinition($this->prefix('manager'));
$services = $builder->findByTag(self::TAG_SUBSCRIBER);
foreach ($services as $serviceName => $meta) {
$manager->addSetup('addEventSubscriber',
array('@' . $serviceName));
}
afterCompile($class)
use NettePhpGenerator as Code;
public function afterCompile(CodeClassType $class)
{
$config = $this->getConfig();
$initialize = $class->methods['initialize'];
$initialize->addBody('date_default_timezone_set(?);',
array($config['date.timezone']));
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ší)
Závislosti rozšíření - ask
use KdybyDoctrineDIIDatabaseTypeProvider;
$exts = $this->compiler
->getExtensions(IDatabaseTypeProvider::class);
foreach ($exts as $ext) {
$types = $ext->getDatabaseTypes();
// ...
Závislosti rozšíření - tell
use KdybyDoctrineDIOrmExtension;
$exts = $this->compiler
->getExtensions(OrmExtension::class);
$exts[0]->addDatabaseType($metadata);
Dotazy?
Díky za pozornost!
filip-prochazka.com
Follow me maybe? @ProchazkaFilip

Contenu connexe

Tendances

CRCE - přehled datového modelu a vybraná API
CRCE - přehled datového modelu a vybraná APICRCE - přehled datového modelu a vybraná API
CRCE - přehled datového modelu a vybraná API
Premek Brada
 

Tendances (12)

CQRS v rohlik.cz
CQRS v rohlik.czCQRS v rohlik.cz
CQRS v rohlik.cz
 
Rozšiřujeme jQuery aneb proč si nenapsat plugin?
Rozšiřujeme jQuery aneb proč si nenapsat plugin?Rozšiřujeme jQuery aneb proč si nenapsat plugin?
Rozšiřujeme jQuery aneb proč si nenapsat plugin?
 
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
MicroKernel - aneb špatný název pro Helper (5. sraz přátel Symfony v Praze)
 
Clean code
Clean codeClean code
Clean code
 
Drupal Front-end
Drupal Front-endDrupal Front-end
Drupal Front-end
 
CRCE - přehled datového modelu a vybraná API
CRCE - přehled datového modelu a vybraná APICRCE - přehled datového modelu a vybraná API
CRCE - přehled datového modelu a vybraná API
 
201502.ReinIT.Dev
201502.ReinIT.Dev201502.ReinIT.Dev
201502.ReinIT.Dev
 
Jak přemigrovat Slevomat na Doctrine za jedno dopoledne
Jak přemigrovat Slevomat na Doctrine za jedno dopoledneJak přemigrovat Slevomat na Doctrine za jedno dopoledne
Jak přemigrovat Slevomat na Doctrine za jedno dopoledne
 
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
Na co si dát v Javascriptu pozor? - Barcamp Hradec Králové 2015
 
Vývoj aplikací pro iOS
Vývoj aplikací pro iOSVývoj aplikací pro iOS
Vývoj aplikací pro iOS
 
Django
DjangoDjango
Django
 
jQuery: full frontal
jQuery: full frontaljQuery: full frontal
jQuery: full frontal
 

En vedette (11)

Fairy tail 001_24
Fairy tail 001_24Fairy tail 001_24
Fairy tail 001_24
 
Triangulodesuelostextura
TriangulodesuelostexturaTriangulodesuelostextura
Triangulodesuelostextura
 
2015_CTI_BSc-IT_Module-Description_Final1
2015_CTI_BSc-IT_Module-Description_Final12015_CTI_BSc-IT_Module-Description_Final1
2015_CTI_BSc-IT_Module-Description_Final1
 
Cover page (joriz)
Cover page (joriz)Cover page (joriz)
Cover page (joriz)
 
the language of literaure
the language of literaurethe language of literaure
the language of literaure
 
Poblacio d'Espanya (II)
Poblacio d'Espanya (II)Poblacio d'Espanya (II)
Poblacio d'Espanya (II)
 
Climate and weather
Climate and weatherClimate and weather
Climate and weather
 
εφηβεία
εφηβείαεφηβεία
εφηβεία
 
Testování prakticky
Testování praktickyTestování prakticky
Testování prakticky
 
Value Added Architecture2
Value Added Architecture2Value Added Architecture2
Value Added Architecture2
 
HEALTHCARE ARCHITECTURE
HEALTHCARE ARCHITECTUREHEALTHCARE ARCHITECTURE
HEALTHCARE ARCHITECTURE
 

Similaire à Nette framework - How to compile an extensible di container

Lex Vjatkin + Ondřej procházka: Jak to děláme ve Wikidi
Lex Vjatkin + Ondřej procházka: Jak to děláme ve WikidiLex Vjatkin + Ondřej procházka: Jak to děláme ve Wikidi
Lex Vjatkin + Ondřej procházka: Jak to děláme ve Wikidi
Develcz
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
Jiří Matula
 

Similaire à Nette framework - How to compile an extensible di container (20)

MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
MicroKernel aneb spatny nazev pro Helper (5. sraz pratel Symfony)
 
Zend Framework 2.0 (ZFMeetup Praha 3.11.2011)
Zend Framework 2.0 (ZFMeetup Praha 3.11.2011)Zend Framework 2.0 (ZFMeetup Praha 3.11.2011)
Zend Framework 2.0 (ZFMeetup Praha 3.11.2011)
 
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
Miroslav Bajtoš - Nativní async/await v Node.js - už tam jsme?
 
MoroSystems na ostravském CZJUGu o Apache Wicket
MoroSystems na ostravském CZJUGu o Apache WicketMoroSystems na ostravském CZJUGu o Apache Wicket
MoroSystems na ostravském CZJUGu o Apache Wicket
 
Czechitas - školení PHP/Symfony MicroKernel
Czechitas - školení PHP/Symfony MicroKernelCzechitas - školení PHP/Symfony MicroKernel
Czechitas - školení PHP/Symfony MicroKernel
 
Silex
SilexSilex
Silex
 
Dependency injection v .Net Frameworku
Dependency injection v .Net FrameworkuDependency injection v .Net Frameworku
Dependency injection v .Net Frameworku
 
Technologie užívané při vývoji velkých e-shopů
Technologie užívané při vývoji velkých e-shopůTechnologie užívané při vývoji velkých e-shopů
Technologie užívané při vývoji velkých e-shopů
 
Testování v PHP
Testování v PHPTestování v PHP
Testování v PHP
 
ADO.NET
ADO.NETADO.NET
ADO.NET
 
Lex Vjatkin + Ondřej procházka: Jak to děláme ve Wikidi
Lex Vjatkin + Ondřej procházka: Jak to děláme ve WikidiLex Vjatkin + Ondřej procházka: Jak to děláme ve Wikidi
Lex Vjatkin + Ondřej procházka: Jak to děláme ve Wikidi
 
Petr Heinz - Čisté testy, dobré testy
Petr Heinz - Čisté testy, dobré testyPetr Heinz - Čisté testy, dobré testy
Petr Heinz - Čisté testy, dobré testy
 
React premature performance optimization
React premature performance optimizationReact premature performance optimization
React premature performance optimization
 
ASP.NET 3.5 / futures
ASP.NET 3.5 / futuresASP.NET 3.5 / futures
ASP.NET 3.5 / futures
 
R85 Designer Tcl
R85 Designer TclR85 Designer Tcl
R85 Designer Tcl
 
R85 Designer
R85 DesignerR85 Designer
R85 Designer
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Android Development for Phone and Tablet
Android Development for Phone and TabletAndroid Development for Phone and Tablet
Android Development for Phone and Tablet
 
Spring ioc-advanced
Spring ioc-advancedSpring ioc-advanced
Spring ioc-advanced
 
Použití Next.js a Reactí UI khinihovny v aplikaci
Použití Next.js a Reactí UI khinihovny v aplikaciPoužití Next.js a Reactí UI khinihovny v aplikaci
Použití Next.js a Reactí UI khinihovny v aplikaci
 

Plus de Filip Procházka (6)

4 roky remote
4 roky remote4 roky remote
4 roky remote
 
Před čím vás Nette ani Symfony neochrání
Před čím vás Nette ani Symfony neochráníPřed čím vás Nette ani Symfony neochrání
Před čím vás Nette ani Symfony neochrání
 
Nejlepší cache je žádná cache
Nejlepší cache je žádná cacheNejlepší cache je žádná cache
Nejlepší cache je žádná cache
 
Kdyby/Translation
Kdyby/TranslationKdyby/Translation
Kdyby/Translation
 
Nette Tester / Posobota
Nette Tester / PosobotaNette Tester / Posobota
Nette Tester / Posobota
 
Composer / Posobota
Composer / PosobotaComposer / Posobota
Composer / Posobota
 

Nette framework - How to compile an extensible di container