D8: DI, DIC, Services
Photo by Carli Jeen on Unsplash
The root!
What is a good framework
for you?
-
easy to use
-
secure
-
extendable
-
stable
extendable
great DX?
+
Gonna make this?
Dependency Injection
class Laptop {
public function getStatusInfo() {
$cpu = new Intel();
$cpu->getStatus();
}
}
$laptop = new Laptop();
$laptop->getStatusInfo();
class Laptop {
protected $cpu;
public function __construct(Intell $cpu) {
$this->cpu = $cpu;
}
public function getStatusInfo() {
$this->cpu->getStatus();
}
}
$cpu = new Intel();
$laptop = new Laptop($cpu);
$laptop->getStatusInfo();
interface CpuInterface {
public function getStatus();
}
class Laptop {
protected $cpu;
public function __construct(CpuInterface $cpu) {
$this->cpu = $cpu;
}
public function getStatusInfo() {
$this->cpu->getStatus();
}
}
$cpu = new Intel();
$laptop = new Laptop($cpu);
$laptop->getStatusInfo();
👍
DI
DI Container
// Who should do this? I don't want!
// I want to get somewhere this objects.
$cpu = new Intel();
$laptop = new Laptop($cpu);
...
// And finally...
$laptop->getStatusInfo();
DIC
?
// Somewhere in framework code.
$dic = new DIC();
$dic->register('cpu_provider', function() {
return new Intel();
});
$dic->register('laptop_provider', function() use($dic) {
return new Laptop($dic->resolve('cpu_provider'));
});
...
// Somewhere in my code
$laptop = $dic->resolve('laptop_provider');
$laptop->getStatusInfo();
🚀
DIC
The main goal of IoC and DI is to remove dependencies of an application. This makes the system more decoupled and maintainable.
💡
What is a service?
Services
for procedural guys
require_once MY_SUPER_USEFUL_LIBRARY . '/payment.paypal.api.php';
$payment = payment_paypal_get_api();
$payment->connect();
in AngularJS
- provides method to keep data across the lifetime of the app
- provides method to communicate data across the controllers in a consistent way
- used to organize and share data and functions across the application
😀
in Drupal
In Drupal 8 speak, a service is any object managed by the services container.
Drupal 8 introduces the concept of services to decouple reusable functionality and makes these services pluggable and replaceable by registering them with a service container.
core.services.yml
Service
twig:
class: Drupal\Core\Template\TwigEnvironment
arguments: ['@app.root', ... , '%twig_extension_hash%', ... ]
tags:
- { name: service_collector, tag: 'twig.extension', call: addExtension }
twig.extension:
class: Drupal\Core\Template\TwigExtension
arguments: ['@renderer', ...]
tags:
- { name: twig.extension, priority: 100 }
machine name
implementation
dependencies
filters
config variable
service
definitions
static
*.services.yml
user.auth:
class: Drupal\user\UserAuth
arguments: ['@entity.manager', '@password']
YML
CLASS
define
alter
namespace Drupal\my_module;
class MyModuleServiceProvider implements ServiceModifierInterface {
public function alter(ContainerBuilder $container) {
$definition = $container->getDefinition('language_manager');
$definition->setClass('Drupal\my_module\LanguageManager')
->addArgument(new Reference('config.factory'))
}
}
programmatic
programmatic
namespace Drupal\my_module;
class MyModuleServiceProvider implements ServiceProviderInterface {
public function register(ContainerBuilder $container) {
if ($this->isMultilingual()) {
$container->register(
'mymodule_request_subscriber',
'Drupal\my_module\EventSubscriber\LanguageRequestSubscriber'
)
->addTag('event_subscriber')
->addArgument(new Reference('language_manager'))
}
}
}
service
usage
define dependencies
services:
local_translator.user_skills:
class: Drupal\local_translator\Services\LocalTranslatorUserSkills
arguments: ['@current_user', '@config.factory']
inject dependencies in code
class TranslationStatus extends Boolean implements ContainerFactoryPluginInterface {
public function __construct(array $configuration, $plugin_definition, LangManagerInterface $manager) {
parent::__construct($configuration, $plugin_definition);
$this->languageManager = $manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_definition) {
return new static(
$configuration, $plugin_id, $plugin_definition,
$container->get('language_manager')
);
}
}
$container->get('language_manager')
problem
solution
result
Links
https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO
https://pimple.symfony.com
https://github.com/rdlowrey/Auryn
Founder @
Co- Founder @
Vladyslav Moyseenko, a.k.a vlad.dancer
&
D8 School: Services, DI, DIC
By Vlad Moyseenko
D8 School: Services, DI, DIC
- 561