SlideShare uma empresa Scribd logo
1 de 57
Baixar para ler offline
Dependency Injection in
Drupal 8
By Alexei Gorobets
asgorobets
Why talk about DI?
* Drupal 8 is coming…
* DI is a commonly used pattern in software
design
The problems in D7
1. Strong dependencies
* Globals:
- users
- database
- language
- paths
* EntityFieldQuery still assumes SQL in
property queries
* Views assumes SQL database.
The problems in D7
2. No way to reuse.
* Want to change a small part of contrib code?
Copy the callback entirely and replace it with your code.
The problems in D7
3. A lot of clutter happening.
* Use of preprocess to do calculations.
* Excessive use of alter hooks for some major
replacements.
* PHP in template files? Huh =)
The problems in D7
4. How can we test something?
* Pass dummy DB connection?
NO.
* Create mock objects?
NO.
* Want a simple test class?
Bootstrap Drupal first.
How we want our code to look like?
How it actually looks?
This talk is about
* DI Design Pattern
* DI in Symfony
* DI in Drupal 8
Our goal:
Let’s take a wrong approach
Some procedural code
function foo_bar($foo) {
global $user;
if ($user->uid != 0) {
$nodes = db_query("SELECT * FROM {node}")->fetchAll();
}
// Load module file that has the function.
module_load_include('inc', cool_module, 'cool.admin');
node_make_me_look_cool(NOW());
}
Some procedural code
function foo_bar($foo) {
global $user;
if ($user->uid != 0) {
$nodes = db_query("SELECT * FROM {node}")->fetchAll();
}
// Load module file that has the function.
module_load_include('inc', cool_module, 'cool.admin');
node_make_me_look_cool(NOW());
}
* foo_bar knows about the user object.
* node_make_me_look_cool needs a function from another module.
* You need bootstrapped Drupal to use module_load_include, or at least include the file that declares it.
* foo_bar assumes some default database connection.
Let’s try an OO approach
User class uses sessions to store language
class SessionStorage
{
function __construct($cookieName = 'PHP_SESS_ID')
{
session_name($cookieName);
session_start();
}
function set($key, $value)
{
$_SESSION[$key] = $value;
}
function get($key)
{
return $_SESSION[$key];
}
// ...
}
class User
{
protected $storage;
function __construct()
{
$this->storage = new SessionStorage();
}
function setLanguage($language)
{
$this->storage->set('language', $language);
}
function getLanguage()
{
return $this->storage->get('language');
}
// ...
}
Working with User
$user = new User();
$user->setLanguage('fr');
$user_language = $user->getLanguage();
Working with such code is damn easy.
What could possibly go wrong here?
What if?
What if we want to change a session cookie name?
What if?
What if we want to change a session cookie name?
class User
{
function __construct()
{
$this->storage = new SessionStorage('SESSION_ID');
}
// ...
}
Hardcode the name in User’s constructor
What if?
class User
{
function __construct()
{
$this->storage = new SessionStorage
(STORAGE_SESSION_NAME);
}
// ...
}
define('STORAGE_SESSION_NAME', 'SESSION_ID');
Define a constant
What if we want to change a session cookie name?
What if?
class User
{
function __construct($sessionName)
{
$this->storage = new SessionStorage($sessionName);
}
// ...
}
$user = new User('SESSION_ID');
Send cookie name as User argument
What if we want to change a session cookie name?
What if?
class User
{
function __construct($storageOptions)
{
$this->storage = new SessionStorage($storageOptions
['session_name']);
}
// ...
}
$user = new User(array('session_name' => 'SESSION_ID'));
Send an array of options as User argument
What if we want to change a session cookie name?
What if?
What if we want to change a session storage?
For instance to store sessions in DB or files
What if?
What if we want to change a session storage?
For instance to store sessions in DB or files
You need to change User class
Introducing Dependency Injection
Here it is:
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
// ...
}
Instead of instantiating the storage in User, let’s just
pass it from outside.
Here it is:
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
// ...
}
Instead of instantiating the storage in User, let’s just
pass it from outside.
$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
Types of injections:
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
}
class User
{
function setSessionStorage($storage)
{
$this->storage = $storage;
}
}
class User
{
public $sessionStorage;
}
$user->sessionStorage = $storage;
Constructor injection
Setter injection
Property injection
Ok, where does injection happen?
$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
Where should this code be?
Ok, where does injection happen?
$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
Where should this code be?
* Manual injection
* Injection in a factory class
* Using a container/injector
How frameworks do that?
Dependency Injection Container (DIC)
or
Service container
What is a Service?
Service is any PHP object that
performs some sort of "global"
task
Let’s say we have a class
class Mailer
{
private $transport;
public function __construct($transport)
{
$this->transport = $transport;
}
// ...
}
How to make it a service?
Using YAML
parameters:
mailer.class: Mailer
mailer.transport: sendmail
services:
mailer:
class: "%mailer.class%"
arguments: ["%my_mailer.transport%"]
Using YAML
parameters:
mailer.class: Mailer
mailer.transport: sendmail
services:
mailer:
class: "%mailer.class%"
arguments: ["%my_mailer.transport%"]
Loading a service from yml file.
require_once '/PATH/TO/sfServiceContainerAutoloader.php';
sfServiceContainerAutoloader::register();
$sc = new sfServiceContainerBuilder();
$loader = new sfServiceContainerLoaderFileYaml($sc);
$loader->load('/somewhere/services.yml');
Use PHP Dumper to create PHP file once
$name = 'Project'.md5($appDir.$isDebug.$environment).'ServiceContainer';
$file = sys_get_temp_dir().'/'.$name.'.php';
if (!$isDebug && file_exists($file))
{
require_once $file;
$sc = new $name();
}
else
{
// build the service container dynamically
$sc = new sfServiceContainerBuilder();
$loader = new sfServiceContainerLoaderFileXml($sc);
$loader->load('/somewhere/container.xml');
if (!$isDebug)
{
$dumper = new sfServiceContainerDumperPhp($sc);
file_put_contents($file, $dumper->dump(array('class' => $name));
}
}
Use Graphviz dumper for this beauty
Symfony terminology
Symfony terminology
Compile the container
There is no reason to pull configurations on every
request. We just compile the container in a PHP class
with hardcoded methods for each service.
container->compile();
Compiler passes
Compiler passes are classes that process the container,
giving you an opportunity to manipulate existing service
definitions.
Use them to:
● Specify a different class for a given serviceid
● Process“tagged”services
Compiler passes
Tagged services
There is a way to tag services for further processing in
compiler passes.
This technique is used to register event subscribers to
Symfony’s event dispatcher.
Tagged services
Event subscribers
Event subscribers
Changing registered service
1. Write OO code and get wired into the container.
2. In case of legacy procedural code you can use:
Drupal::service(‘some_service’);
Example:
Drupal 7:
$path = $_GET['q']
Drupal 8:
$request = Drupal::service('request');
$path = $request->attributes->get('_system_path');
Ways to use core’s services
● The Drupal Kernel :
core/lib/Drupal/Core/DrupalKernel.php
● Services are defined in: core/core.services.
yml
● Compiler passes get added in:
core/lib/Drupal/Core/CoreServiceProvider.
php
● Compiler pass classes are in:
core/lib/Drupal/Core/DependencyInjection/
Compiler/
Where the magic happens?
● Define module services in :
mymodule/mymodule.services.yml
● Compiler passes get added in:
mymodule/lib/Drupal/mymodule/Mymodule
ServiceProvider.php
● All classes including Compiler class
classes live in:
mymodule/lib/Drupal/mymodule
What about modules?
Resources:
● Fabien Potencier’s “What is Dependency
Injection” series
● Symfony Service Container
● Symfony Dependency Injection Component
● WSCCI Conversion Guide
● Change notice: Use Dependency Injection to
handle global PHP objects
$slide = new Questions();
$current_slide = new Slide($slide);
Dependency injection in Drupal 8

Mais conteúdo relacionado

Mais procurados

Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Development Approach
Development ApproachDevelopment Approach
Development Approachalexkingorg
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationKirill Chebunin
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5Jason Austin
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHPLorna Mitchell
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindiappsdevelopment
 
Class 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingClass 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingAhmed Swilam
 
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usagePavel Makhrinsky
 
Puppet DSL gotchas, and understandiing Roles & Profiles pattern
Puppet DSL gotchas, and understandiing Roles & Profiles patternPuppet DSL gotchas, and understandiing Roles & Profiles pattern
Puppet DSL gotchas, and understandiing Roles & Profiles patternAlex Simenduev
 
Dependency Injection in Drupal 8
Dependency Injection in Drupal 8Dependency Injection in Drupal 8
Dependency Injection in Drupal 8katbailey
 
Drupal 8: Entities
Drupal 8: EntitiesDrupal 8: Entities
Drupal 8: Entitiesdrubb
 
Drupal 8: Routing & More
Drupal 8: Routing & MoreDrupal 8: Routing & More
Drupal 8: Routing & Moredrubb
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpMichael Girouard
 

Mais procurados (20)

Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Development Approach
Development ApproachDevelopment Approach
Development Approach
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHP
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in php
 
Class 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented ProgrammingClass 7 - PHP Object Oriented Programming
Class 7 - PHP Object Oriented Programming
 
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usage
 
Puppet DSL gotchas, and understandiing Roles & Profiles pattern
Puppet DSL gotchas, and understandiing Roles & Profiles patternPuppet DSL gotchas, and understandiing Roles & Profiles pattern
Puppet DSL gotchas, and understandiing Roles & Profiles pattern
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Dependency Injection in Drupal 8
Dependency Injection in Drupal 8Dependency Injection in Drupal 8
Dependency Injection in Drupal 8
 
Drupal 8: Entities
Drupal 8: EntitiesDrupal 8: Entities
Drupal 8: Entities
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
Drupal 8: Routing & More
Drupal 8: Routing & MoreDrupal 8: Routing & More
Drupal 8: Routing & More
 
Drupal 8 migrate!
Drupal 8 migrate!Drupal 8 migrate!
Drupal 8 migrate!
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
A Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented PhpA Gentle Introduction To Object Oriented Php
A Gentle Introduction To Object Oriented Php
 

Destaque

Media management in Drupal @Moldcamp
Media management in Drupal @MoldcampMedia management in Drupal @Moldcamp
Media management in Drupal @MoldcampAlexei Gorobets
 
Создание дистрибутивов Drupal. Почему, зачем и как?
Создание дистрибутивов Drupal. Почему, зачем и как?Создание дистрибутивов Drupal. Почему, зачем и как?
Создание дистрибутивов Drupal. Почему, зачем и как?Alexei Gorobets
 
Extending media presentation
Extending media presentationExtending media presentation
Extending media presentationAlexei Gorobets
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampAlexei Gorobets
 
Real-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet ElasticsearchReal-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet ElasticsearchAlexei Gorobets
 

Destaque (7)

Why drupal
Why drupalWhy drupal
Why drupal
 
Media management in Drupal @Moldcamp
Media management in Drupal @MoldcampMedia management in Drupal @Moldcamp
Media management in Drupal @Moldcamp
 
Создание дистрибутивов Drupal. Почему, зачем и как?
Создание дистрибутивов Drupal. Почему, зачем и как?Создание дистрибутивов Drupal. Почему, зачем и как?
Создание дистрибутивов Drupal. Почему, зачем и как?
 
Extending media presentation
Extending media presentationExtending media presentation
Extending media presentation
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
 
Real-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet ElasticsearchReal-time search in Drupal. Meet Elasticsearch
Real-time search in Drupal. Meet Elasticsearch
 
Migrate in Drupal 8
Migrate in Drupal 8Migrate in Drupal 8
Migrate in Drupal 8
 

Semelhante a Dependency injection in Drupal 8

PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodeSWIFTotter Solutions
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Fabien Potencier
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentTammy Hart
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 3camp
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboardsDenis Ristic
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingTricode (part of Dept)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)James Titcumb
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 

Semelhante a Dependency injection in Drupal 8 (20)

PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Design patterns in PHP
Design patterns in PHPDesign patterns in PHP
Design patterns in PHP
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
OOP
OOPOOP
OOP
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 

Último

Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 

Último (20)

Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Dependency injection in Drupal 8

  • 1. Dependency Injection in Drupal 8 By Alexei Gorobets asgorobets
  • 2. Why talk about DI? * Drupal 8 is coming… * DI is a commonly used pattern in software design
  • 3. The problems in D7 1. Strong dependencies * Globals: - users - database - language - paths * EntityFieldQuery still assumes SQL in property queries * Views assumes SQL database.
  • 4. The problems in D7 2. No way to reuse. * Want to change a small part of contrib code? Copy the callback entirely and replace it with your code.
  • 5. The problems in D7 3. A lot of clutter happening. * Use of preprocess to do calculations. * Excessive use of alter hooks for some major replacements. * PHP in template files? Huh =)
  • 6. The problems in D7 4. How can we test something? * Pass dummy DB connection? NO. * Create mock objects? NO. * Want a simple test class? Bootstrap Drupal first.
  • 7. How we want our code to look like?
  • 8.
  • 10.
  • 11. This talk is about * DI Design Pattern * DI in Symfony * DI in Drupal 8
  • 13. Let’s take a wrong approach
  • 14. Some procedural code function foo_bar($foo) { global $user; if ($user->uid != 0) { $nodes = db_query("SELECT * FROM {node}")->fetchAll(); } // Load module file that has the function. module_load_include('inc', cool_module, 'cool.admin'); node_make_me_look_cool(NOW()); }
  • 15. Some procedural code function foo_bar($foo) { global $user; if ($user->uid != 0) { $nodes = db_query("SELECT * FROM {node}")->fetchAll(); } // Load module file that has the function. module_load_include('inc', cool_module, 'cool.admin'); node_make_me_look_cool(NOW()); } * foo_bar knows about the user object. * node_make_me_look_cool needs a function from another module. * You need bootstrapped Drupal to use module_load_include, or at least include the file that declares it. * foo_bar assumes some default database connection.
  • 16. Let’s try an OO approach
  • 17. User class uses sessions to store language class SessionStorage { function __construct($cookieName = 'PHP_SESS_ID') { session_name($cookieName); session_start(); } function set($key, $value) { $_SESSION[$key] = $value; } function get($key) { return $_SESSION[$key]; } // ... } class User { protected $storage; function __construct() { $this->storage = new SessionStorage(); } function setLanguage($language) { $this->storage->set('language', $language); } function getLanguage() { return $this->storage->get('language'); } // ... }
  • 18. Working with User $user = new User(); $user->setLanguage('fr'); $user_language = $user->getLanguage(); Working with such code is damn easy. What could possibly go wrong here?
  • 19. What if? What if we want to change a session cookie name?
  • 20. What if? What if we want to change a session cookie name? class User { function __construct() { $this->storage = new SessionStorage('SESSION_ID'); } // ... } Hardcode the name in User’s constructor
  • 21. What if? class User { function __construct() { $this->storage = new SessionStorage (STORAGE_SESSION_NAME); } // ... } define('STORAGE_SESSION_NAME', 'SESSION_ID'); Define a constant What if we want to change a session cookie name?
  • 22. What if? class User { function __construct($sessionName) { $this->storage = new SessionStorage($sessionName); } // ... } $user = new User('SESSION_ID'); Send cookie name as User argument What if we want to change a session cookie name?
  • 23. What if? class User { function __construct($storageOptions) { $this->storage = new SessionStorage($storageOptions ['session_name']); } // ... } $user = new User(array('session_name' => 'SESSION_ID')); Send an array of options as User argument What if we want to change a session cookie name?
  • 24. What if? What if we want to change a session storage? For instance to store sessions in DB or files
  • 25. What if? What if we want to change a session storage? For instance to store sessions in DB or files You need to change User class
  • 27.
  • 28. Here it is: class User { function __construct($storage) { $this->storage = $storage; } // ... } Instead of instantiating the storage in User, let’s just pass it from outside.
  • 29. Here it is: class User { function __construct($storage) { $this->storage = $storage; } // ... } Instead of instantiating the storage in User, let’s just pass it from outside. $storage = new SessionStorage('SESSION_ID'); $user = new User($storage);
  • 30. Types of injections: class User { function __construct($storage) { $this->storage = $storage; } } class User { function setSessionStorage($storage) { $this->storage = $storage; } } class User { public $sessionStorage; } $user->sessionStorage = $storage; Constructor injection Setter injection Property injection
  • 31. Ok, where does injection happen? $storage = new SessionStorage('SESSION_ID'); $user = new User($storage); Where should this code be?
  • 32. Ok, where does injection happen? $storage = new SessionStorage('SESSION_ID'); $user = new User($storage); Where should this code be? * Manual injection * Injection in a factory class * Using a container/injector
  • 33. How frameworks do that? Dependency Injection Container (DIC) or Service container
  • 34. What is a Service?
  • 35. Service is any PHP object that performs some sort of "global" task
  • 36. Let’s say we have a class class Mailer { private $transport; public function __construct($transport) { $this->transport = $transport; } // ... }
  • 37. How to make it a service?
  • 38. Using YAML parameters: mailer.class: Mailer mailer.transport: sendmail services: mailer: class: "%mailer.class%" arguments: ["%my_mailer.transport%"]
  • 39. Using YAML parameters: mailer.class: Mailer mailer.transport: sendmail services: mailer: class: "%mailer.class%" arguments: ["%my_mailer.transport%"] Loading a service from yml file. require_once '/PATH/TO/sfServiceContainerAutoloader.php'; sfServiceContainerAutoloader::register(); $sc = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileYaml($sc); $loader->load('/somewhere/services.yml');
  • 40. Use PHP Dumper to create PHP file once $name = 'Project'.md5($appDir.$isDebug.$environment).'ServiceContainer'; $file = sys_get_temp_dir().'/'.$name.'.php'; if (!$isDebug && file_exists($file)) { require_once $file; $sc = new $name(); } else { // build the service container dynamically $sc = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileXml($sc); $loader->load('/somewhere/container.xml'); if (!$isDebug) { $dumper = new sfServiceContainerDumperPhp($sc); file_put_contents($file, $dumper->dump(array('class' => $name)); } }
  • 41. Use Graphviz dumper for this beauty
  • 44. Compile the container There is no reason to pull configurations on every request. We just compile the container in a PHP class with hardcoded methods for each service. container->compile();
  • 45. Compiler passes Compiler passes are classes that process the container, giving you an opportunity to manipulate existing service definitions. Use them to: ● Specify a different class for a given serviceid ● Process“tagged”services
  • 47. Tagged services There is a way to tag services for further processing in compiler passes. This technique is used to register event subscribers to Symfony’s event dispatcher.
  • 52. 1. Write OO code and get wired into the container. 2. In case of legacy procedural code you can use: Drupal::service(‘some_service’); Example: Drupal 7: $path = $_GET['q'] Drupal 8: $request = Drupal::service('request'); $path = $request->attributes->get('_system_path'); Ways to use core’s services
  • 53. ● The Drupal Kernel : core/lib/Drupal/Core/DrupalKernel.php ● Services are defined in: core/core.services. yml ● Compiler passes get added in: core/lib/Drupal/Core/CoreServiceProvider. php ● Compiler pass classes are in: core/lib/Drupal/Core/DependencyInjection/ Compiler/ Where the magic happens?
  • 54. ● Define module services in : mymodule/mymodule.services.yml ● Compiler passes get added in: mymodule/lib/Drupal/mymodule/Mymodule ServiceProvider.php ● All classes including Compiler class classes live in: mymodule/lib/Drupal/mymodule What about modules?
  • 55. Resources: ● Fabien Potencier’s “What is Dependency Injection” series ● Symfony Service Container ● Symfony Dependency Injection Component ● WSCCI Conversion Guide ● Change notice: Use Dependency Injection to handle global PHP objects
  • 56. $slide = new Questions(); $current_slide = new Slide($slide);