SlideShare a Scribd company logo
1 of 27
Présentation par Vlad RIABCHENKO
Injection de dépendances dans Symfony >= 3.3
28
Nov 2017
Conteneur de services et
injection de dépendances
D I d a n s S y m f o n y > = 3 . 3
C o n t e n e u r d e s s e r v i c e s
D I d a n s S y m f o n y > = 3 . 3
Définitions Objets prêts-à-utiliser
$container->get('mailer');
$container->get('doctrine');
$container->get('app.customer');
app.customer:
class: AppBundleServiceCustomerSerivce
I n j e c t i o n d e d é p e n d a n c e s
D I d a n s S y m f o n y > = 3 . 3
But du conteneur de services:
• Garder les services et les fournir par son nom
• Instancier les services seulement à la demande
• Instancier les services en se basant sur leurs définitions
• Instancier les services en les approvisionnant de leur dépendances
app.form.user_type:
class: AppBundleFormUserType
arguments: ["@app.user"]
app.user:
class: AppBundleServiceUserService
arguments: ["@mailer"]
I n j e c t i o n d e d é p e n d a n c e s
D I d a n s S y m f o n y > = 3 . 3
app.form.user_type:
class: AppBundleFormUserType
arguments: ["@app.user"]
app.user:
class: AppBundleServiceUserService
arguments: ["@mailer"]
mailer:
class: Swift_Mailer
class UserService
{
public function __construct(Swift_Mailer $mailer)
{ }
}
class UserType
{
public function __construct(UserService $userSerivce)
{}
}
class Swift_Mailer
{ }
Autowiring
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
D I d a n s S y m f o n y > = 3 . 3
Autowiring simplifie la configuration de vos services.
Il lit les indications de type (Type-hints) sur le constructeur et passe automatiquement
les services corrects.
class UserType
{
/**
* Constructeur
*
* @param UserService $userService
* @param TokenStorageInterface $tokenStorage
* @param UrlGeneratorInterface $router
*/
public function __construct(
UserService $userService,
TokenStorageInterface $tokenStorage,
UrlGeneratorInterface $router
) { }
}
#services.yml
app.form.user_type:
class: AppBundleFormUserType
arguments:
- "@app.user"
- "@security.token_storage"
- "@router"
#services.yml
app.form.user_type:
class: AppBundleFormUserType
autowire: true
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
Il est possible de lister les services qui peuvent être autowired pour savoir quelle
classe/interfase il faut spécifier dans les paramètres de constructeur.
# php bin/console debug:container --types
------------------------------------------------------------------------------------ --------------------------------------------------------
Service ID Class name
------------------------------------------------------------------------------------ --------------------------------------------------------
AppBundleFormUserType AppBundleFormUserType
AppBundleServiceUserServiceA AppBundleServiceUserServiceA
AppBundleServiceUserServiceB AppBundleServiceUserServiceB
AppBundleServiceUserServiceInterface alias for "AppBundleServiceUserServiceA"
DoctrineCommonAnnotationsReader alias for "annotations.cached_reader"
DoctrineCommonPersistenceManagerRegistry alias for "doctrine"
DoctrineCommonPersistenceObjectManager alias for "doctrine.orm.default_entity_manager"
DoctrineDBALConnection alias for "doctrine.dbal.default_connection"
DoctrineDBALDriverConnection alias for "doctrine.dbal.default_connection"
DoctrineORMEntityManagerInterface alias for "doctrine.orm.default_entity_manager"
PsrCacheCacheItemPoolInterface alias for "cache.app"
PsrContainerContainerInterface alias for "service_container"
PsrLogLoggerInterface alias for "monolog.logger"
SessionHandlerInterface alias for "session.handler.native_file"
Swift_Mailer alias for "swiftmailer.mailer.default"
Swift_Spool alias for "swiftmailer.mailer.default.spool.memory"
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
class UserType
{
/**
* Constructeur
*
* @param UserServiceInterface $userService
*/
public function __construct(
UserServiceInterface $userService
) { }
}
Indications de type par interfaces.
(1/1) AutowiringFailedException
Cannot autowire service "app.form.user_type": argument "$userService" of
method "AppBundleFormUserType::__construct()" references interface
"AppBundleServiceUserServiceInterface" but no such service exists.
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
Nom de service = FQCN (fully qualified class name)
#services.yml
app.form.user_type:
class: AppBundleFormUserType
autowire: true
app.user.a:
class: AppBundleServiceUserServiceA
autowire: true
app.user.b:
class: AppBundleServiceUserServiceB
#services.yml
AppBundleFormUserType:
autowire: true
AppBundleServiceUserServiceA:
autowire: true
AppBundleServiceUserServiceB: ~
$this->get('app.form.user_type'); $this->get(UserType::class);
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
#services.yml
AppBundleFormUserType:
autowire: true
AppBundleServiceUserServiceA:
autowire: true
AppBundleServiceUserServiceB: ~
AppBundleServiceUserServiceInterface:
alias: "@AppBundleServiceUserServiceA"
AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA"
Alias est la solution pour l’indications de type par interfaces.
Scalar values (parameters)
D I d a n s S y m f o n y > = 3 . 3
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
(1/1) AutowiringFailedException
Cannot autowire service "AppBundleFormUserType": argument "$minOrder" of method "__construct()" must have a type-
hint or be given a value explicitly.
class UserType
{
/**
* Constructeur
*
* @param UserServiceInterface $userService
* @param float $minOrder
* @param int $defaultCity
*/
public function __construct(
UserServiceInterface $userService,
$minOrder,
$defaultCity
) { }
}
#services.yml
parameters:
min_order: 50.5
default_city: Paris
services:
AppBundleFormUserType:
autowire: true
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
class UserType
{
/**
* Constructeur
*
* @param UserServiceInterface $userService
* @param float $minOrder
* @param int $defaultCity
*/
public function __construct(
UserServiceInterface $userService,
$minOrder,
$defaultCity
) { }
}
#services.yml
parameters:
min_order: 50.5
default_city: Paris
services:
AppBundleFormUserType:
autowire: true
arguments:
$defaultCity: "%default_city%"
$minOrder: "%min_order%"
D I d a n s S y m f o n y > = 3 . 3
a u t o wi r e : t r u e
#services.yml
parameters:
min_order: 50.5
default_city: Paris
services:
AppBundleFormUserType:
autowire: true
arguments:
$userService: "@AppBundleServiceUserServiceB"
$defaultCity: "%default_city%"
$minOrder: "%min_order%"
AppBundleServiceUserServiceA:
autowire: true
AppBundleServiceUserServiceB: ~
AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA"
Notion $arg permet spécifier une valeur ou un service souhaité
Autoconfigure
D I d a n s S y m f o n y > = 3 . 3
D I d a n s S y m f o n y > = 3 . 3
a u t o c o n f i g u r e : t r u e
Option autoconfigure enregistre automatiquement vos services en tant que
commandes, event subscribers, types de formulaire etc.
#services.yml
AppBundleFormUserType:
autowire: true
autoconfigure: true
AppBundleEventListenerUserEventSubscriber:
autoconfigure: true
#services.yml
AppBundleFormUserType:
autowire: true
tags: [{name: form.type}]
AppBundleEventListenerUserEventSubscriber:
tags: [{name: kernel.event_subscriber}] class UserEventSubscriber
implements EventSubscriberInterface
{
// implementation
}
class UserType extends AbstractType
{
// implementation
}
D I d a n s S y m f o n y > = 3 . 3
a u t o c o n f i g u r e : t r u e
Autoconfigure se base sur l’instance de service en utilisant operateur instanceof.
Instance tag
FormTypeInterface tags: [form.type]
EventSubscriberInterface tags: [kernel.event_subscriber]
Twig_ExtensionInterface tags: [twig.extension]
SymfonyComponentConsoleCommandCommand tags: [console.command]
… …
D I d a n s S y m f o n y > = 3 . 3
a u t o c o n f i g u r e : t r u e
Autoconfigure fonctionne à l’aide de clé _instanceof.
#services.yml
services:
_instanceof:
AppBundleDomainLoaderInterface:
public: true
tags: ['app.domain_loader']
Tous les services implémentant ce LoaderInterface seront publics et dotés de
‘app.domain_loader’ tag si la clé autoconfigure est activée pour eux.
_defaults
D I d a n s S y m f o n y > = 3 . 3
D I d a n s S y m f o n y > = 3 . 3
_ d e f a u l t s
Clé _defaults permet de spécifier la configuration commune pour les services définis
dans un fichier.
#services.yml
services:
# default configuration for services in *this* file
_defaults:
autowire: true
autoconfigure: true
public: false
AppBundleFormUserType: ~
AppBundleServiceUserServiceA: ~
AppBundleServiceUserServiceB: ~
AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA"
Déclaration groupée
D I d a n s S y m f o n y > = 3 . 3
D I d a n s S y m f o n y > = 3 . 3
D é c l a r a t i o n g r o u p é e
Déclaration groupée permet de réduire beaucoup la taille de configuration.
#services.yml
services:
# default configuration for services in *this* file
_defaults:
autowire: true
autoconfigure: true
public: true
# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA"
Tag controller.service_arguments
D I d a n s S y m f o n y > = 3 . 3
D I d a n s S y m f o n y > = 3 . 3
Ta g c o n t r o l l e r. s e r v i c e _ a r g u m e n t s
Les contrôleurs sont dotés de controller.service_arguments tag pour faire fonctionner
l’autowiring lors d’appelle d’une action.
#services.yml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
AppBundle:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
# controllers are imported separately to make sure they're public
# and have a tag that allows actions to type-hint services
AppBundleController:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
D I d a n s S y m f o n y > = 3 . 3
Ta g c o n t r o l l e r. s e r v i c e _ a r g u m e n t s
class DefaultController extends Controller
{
/**
* /**
* @Route("/", name="homepage")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param UserServiceInterface $userService
* @param LoggerInterface $logger
*/
public function indexAction(
Request $request,
EntityManagerInterface $em,
UserServiceInterface $userService,
LoggerInterface $logger
) { }
}
R ETR OU VEZ W EBN ET
Merci
pour votre attention

More Related Content

What's hot

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
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsŁukasz Chruściel
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Writing Sensible Code
Writing Sensible CodeWriting Sensible Code
Writing Sensible CodeAnis Ahmad
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injectionJosh Adell
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019julien pauli
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Konstantin Kudryashov
 
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
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonfRafael Dohms
 

What's hot (20)

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
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Writing Sensible Code
Writing Sensible CodeWriting Sensible Code
Writing Sensible Code
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injection
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
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)
 
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
 

Similar to Injection de dépendances dans Symfony >= 3.3

How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonKris Wallsmith
 
Jasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casJasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casellentuck
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant TrainingAidIQ
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful RailsViget Labs
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful RailsBen Scofield
 
Dependency Injection in Drupal 8
Dependency Injection in Drupal 8Dependency Injection in Drupal 8
Dependency Injection in Drupal 8katbailey
 
Laravel - Speaking eloquent eloquently
Laravel - Speaking eloquent eloquentlyLaravel - Speaking eloquent eloquently
Laravel - Speaking eloquent eloquentlyLaravel Nigeria
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
How to implement “multiple database(db) connection” in rails3
How to implement “multiple database(db) connection” in rails3How to implement “multiple database(db) connection” in rails3
How to implement “multiple database(db) connection” in rails3Andolasoft Inc
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn Wilker
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 

Similar to Injection de dépendances dans Symfony >= 3.3 (20)

How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
 
Jasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casJasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-cas
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
 
Dependency Injection in Drupal 8
Dependency Injection in Drupal 8Dependency Injection in Drupal 8
Dependency Injection in Drupal 8
 
Speaking Eloquent Eloquently
Speaking Eloquent EloquentlySpeaking Eloquent Eloquently
Speaking Eloquent Eloquently
 
Laravel - Speaking eloquent eloquently
Laravel - Speaking eloquent eloquentlyLaravel - Speaking eloquent eloquently
Laravel - Speaking eloquent eloquently
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
How to implement “multiple database(db) connection” in rails3
How to implement “multiple database(db) connection” in rails3How to implement “multiple database(db) connection” in rails3
How to implement “multiple database(db) connection” in rails3
 
BDD de fuera a dentro
BDD de fuera a dentroBDD de fuera a dentro
BDD de fuera a dentro
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Event Sourcing with php
Event Sourcing with phpEvent Sourcing with php
Event Sourcing with php
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Unit-III.pptx
Unit-III.pptxUnit-III.pptx
Unit-III.pptx
 
Function C programming
Function C programmingFunction C programming
Function C programming
 

More from Vladyslav Riabchenko

Modèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratiqueModèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratiqueVladyslav Riabchenko
 
SOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsSOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsVladyslav Riabchenko
 
Sécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web  à l’aide du composant Security de SymfonySécurisation de vos applications web  à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de SymfonyVladyslav Riabchenko
 
Sécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de SymfonySécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de SymfonyVladyslav Riabchenko
 
Versionning sémantique et Composer
Versionning sémantique et ComposerVersionning sémantique et Composer
Versionning sémantique et ComposerVladyslav Riabchenko
 
Les patrons de conception du composant Form
Les patrons de conception du composant FormLes patrons de conception du composant Form
Les patrons de conception du composant FormVladyslav Riabchenko
 

More from Vladyslav Riabchenko (7)

Modèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratiqueModèle de domaine riche dans une application métier complexe un exemple pratique
Modèle de domaine riche dans une application métier complexe un exemple pratique
 
SOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsSOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applications
 
Sécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web  à l’aide du composant Security de SymfonySécurisation de vos applications web  à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de Symfony
 
Sécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de SymfonySécurisation de vos applications web à l’aide du composant Security de Symfony
Sécurisation de vos applications web à l’aide du composant Security de Symfony
 
Git
GitGit
Git
 
Versionning sémantique et Composer
Versionning sémantique et ComposerVersionning sémantique et Composer
Versionning sémantique et Composer
 
Les patrons de conception du composant Form
Les patrons de conception du composant FormLes patrons de conception du composant Form
Les patrons de conception du composant Form
 

Recently uploaded

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 

Recently uploaded (20)

Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 

Injection de dépendances dans Symfony >= 3.3

  • 1. Présentation par Vlad RIABCHENKO Injection de dépendances dans Symfony >= 3.3 28 Nov 2017
  • 2. Conteneur de services et injection de dépendances D I d a n s S y m f o n y > = 3 . 3
  • 3. C o n t e n e u r d e s s e r v i c e s D I d a n s S y m f o n y > = 3 . 3 Définitions Objets prêts-à-utiliser $container->get('mailer'); $container->get('doctrine'); $container->get('app.customer'); app.customer: class: AppBundleServiceCustomerSerivce
  • 4. I n j e c t i o n d e d é p e n d a n c e s D I d a n s S y m f o n y > = 3 . 3 But du conteneur de services: • Garder les services et les fournir par son nom • Instancier les services seulement à la demande • Instancier les services en se basant sur leurs définitions • Instancier les services en les approvisionnant de leur dépendances app.form.user_type: class: AppBundleFormUserType arguments: ["@app.user"] app.user: class: AppBundleServiceUserService arguments: ["@mailer"]
  • 5. I n j e c t i o n d e d é p e n d a n c e s D I d a n s S y m f o n y > = 3 . 3 app.form.user_type: class: AppBundleFormUserType arguments: ["@app.user"] app.user: class: AppBundleServiceUserService arguments: ["@mailer"] mailer: class: Swift_Mailer class UserService { public function __construct(Swift_Mailer $mailer) { } } class UserType { public function __construct(UserService $userSerivce) {} } class Swift_Mailer { }
  • 6. Autowiring D I d a n s S y m f o n y > = 3 . 3
  • 7. a u t o wi r e : t r u e D I d a n s S y m f o n y > = 3 . 3 Autowiring simplifie la configuration de vos services. Il lit les indications de type (Type-hints) sur le constructeur et passe automatiquement les services corrects. class UserType { /** * Constructeur * * @param UserService $userService * @param TokenStorageInterface $tokenStorage * @param UrlGeneratorInterface $router */ public function __construct( UserService $userService, TokenStorageInterface $tokenStorage, UrlGeneratorInterface $router ) { } } #services.yml app.form.user_type: class: AppBundleFormUserType arguments: - "@app.user" - "@security.token_storage" - "@router" #services.yml app.form.user_type: class: AppBundleFormUserType autowire: true
  • 8. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e Il est possible de lister les services qui peuvent être autowired pour savoir quelle classe/interfase il faut spécifier dans les paramètres de constructeur. # php bin/console debug:container --types ------------------------------------------------------------------------------------ -------------------------------------------------------- Service ID Class name ------------------------------------------------------------------------------------ -------------------------------------------------------- AppBundleFormUserType AppBundleFormUserType AppBundleServiceUserServiceA AppBundleServiceUserServiceA AppBundleServiceUserServiceB AppBundleServiceUserServiceB AppBundleServiceUserServiceInterface alias for "AppBundleServiceUserServiceA" DoctrineCommonAnnotationsReader alias for "annotations.cached_reader" DoctrineCommonPersistenceManagerRegistry alias for "doctrine" DoctrineCommonPersistenceObjectManager alias for "doctrine.orm.default_entity_manager" DoctrineDBALConnection alias for "doctrine.dbal.default_connection" DoctrineDBALDriverConnection alias for "doctrine.dbal.default_connection" DoctrineORMEntityManagerInterface alias for "doctrine.orm.default_entity_manager" PsrCacheCacheItemPoolInterface alias for "cache.app" PsrContainerContainerInterface alias for "service_container" PsrLogLoggerInterface alias for "monolog.logger" SessionHandlerInterface alias for "session.handler.native_file" Swift_Mailer alias for "swiftmailer.mailer.default" Swift_Spool alias for "swiftmailer.mailer.default.spool.memory"
  • 9. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e class UserType { /** * Constructeur * * @param UserServiceInterface $userService */ public function __construct( UserServiceInterface $userService ) { } } Indications de type par interfaces. (1/1) AutowiringFailedException Cannot autowire service "app.form.user_type": argument "$userService" of method "AppBundleFormUserType::__construct()" references interface "AppBundleServiceUserServiceInterface" but no such service exists.
  • 10. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e Nom de service = FQCN (fully qualified class name) #services.yml app.form.user_type: class: AppBundleFormUserType autowire: true app.user.a: class: AppBundleServiceUserServiceA autowire: true app.user.b: class: AppBundleServiceUserServiceB #services.yml AppBundleFormUserType: autowire: true AppBundleServiceUserServiceA: autowire: true AppBundleServiceUserServiceB: ~ $this->get('app.form.user_type'); $this->get(UserType::class);
  • 11. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e #services.yml AppBundleFormUserType: autowire: true AppBundleServiceUserServiceA: autowire: true AppBundleServiceUserServiceB: ~ AppBundleServiceUserServiceInterface: alias: "@AppBundleServiceUserServiceA" AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA" Alias est la solution pour l’indications de type par interfaces.
  • 12. Scalar values (parameters) D I d a n s S y m f o n y > = 3 . 3
  • 13. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e (1/1) AutowiringFailedException Cannot autowire service "AppBundleFormUserType": argument "$minOrder" of method "__construct()" must have a type- hint or be given a value explicitly. class UserType { /** * Constructeur * * @param UserServiceInterface $userService * @param float $minOrder * @param int $defaultCity */ public function __construct( UserServiceInterface $userService, $minOrder, $defaultCity ) { } } #services.yml parameters: min_order: 50.5 default_city: Paris services: AppBundleFormUserType: autowire: true
  • 14. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e class UserType { /** * Constructeur * * @param UserServiceInterface $userService * @param float $minOrder * @param int $defaultCity */ public function __construct( UserServiceInterface $userService, $minOrder, $defaultCity ) { } } #services.yml parameters: min_order: 50.5 default_city: Paris services: AppBundleFormUserType: autowire: true arguments: $defaultCity: "%default_city%" $minOrder: "%min_order%"
  • 15. D I d a n s S y m f o n y > = 3 . 3 a u t o wi r e : t r u e #services.yml parameters: min_order: 50.5 default_city: Paris services: AppBundleFormUserType: autowire: true arguments: $userService: "@AppBundleServiceUserServiceB" $defaultCity: "%default_city%" $minOrder: "%min_order%" AppBundleServiceUserServiceA: autowire: true AppBundleServiceUserServiceB: ~ AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA" Notion $arg permet spécifier une valeur ou un service souhaité
  • 16. Autoconfigure D I d a n s S y m f o n y > = 3 . 3
  • 17. D I d a n s S y m f o n y > = 3 . 3 a u t o c o n f i g u r e : t r u e Option autoconfigure enregistre automatiquement vos services en tant que commandes, event subscribers, types de formulaire etc. #services.yml AppBundleFormUserType: autowire: true autoconfigure: true AppBundleEventListenerUserEventSubscriber: autoconfigure: true #services.yml AppBundleFormUserType: autowire: true tags: [{name: form.type}] AppBundleEventListenerUserEventSubscriber: tags: [{name: kernel.event_subscriber}] class UserEventSubscriber implements EventSubscriberInterface { // implementation } class UserType extends AbstractType { // implementation }
  • 18. D I d a n s S y m f o n y > = 3 . 3 a u t o c o n f i g u r e : t r u e Autoconfigure se base sur l’instance de service en utilisant operateur instanceof. Instance tag FormTypeInterface tags: [form.type] EventSubscriberInterface tags: [kernel.event_subscriber] Twig_ExtensionInterface tags: [twig.extension] SymfonyComponentConsoleCommandCommand tags: [console.command] … …
  • 19. D I d a n s S y m f o n y > = 3 . 3 a u t o c o n f i g u r e : t r u e Autoconfigure fonctionne à l’aide de clé _instanceof. #services.yml services: _instanceof: AppBundleDomainLoaderInterface: public: true tags: ['app.domain_loader'] Tous les services implémentant ce LoaderInterface seront publics et dotés de ‘app.domain_loader’ tag si la clé autoconfigure est activée pour eux.
  • 20. _defaults D I d a n s S y m f o n y > = 3 . 3
  • 21. D I d a n s S y m f o n y > = 3 . 3 _ d e f a u l t s Clé _defaults permet de spécifier la configuration commune pour les services définis dans un fichier. #services.yml services: # default configuration for services in *this* file _defaults: autowire: true autoconfigure: true public: false AppBundleFormUserType: ~ AppBundleServiceUserServiceA: ~ AppBundleServiceUserServiceB: ~ AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA"
  • 22. Déclaration groupée D I d a n s S y m f o n y > = 3 . 3
  • 23. D I d a n s S y m f o n y > = 3 . 3 D é c l a r a t i o n g r o u p é e Déclaration groupée permet de réduire beaucoup la taille de configuration. #services.yml services: # default configuration for services in *this* file _defaults: autowire: true autoconfigure: true public: true # makes classes in src/AppBundle available to be used as services # this creates a service per class whose id is the fully-qualified class name AppBundle: resource: '../../src/AppBundle/*' exclude: '../../src/AppBundle/{Entity,Repository,Tests}' AppBundleServiceUserServiceInterface: "@AppBundleServiceUserServiceA"
  • 24. Tag controller.service_arguments D I d a n s S y m f o n y > = 3 . 3
  • 25. D I d a n s S y m f o n y > = 3 . 3 Ta g c o n t r o l l e r. s e r v i c e _ a r g u m e n t s Les contrôleurs sont dotés de controller.service_arguments tag pour faire fonctionner l’autowiring lors d’appelle d’une action. #services.yml services: _defaults: autowire: true autoconfigure: true public: false AppBundle: resource: '../../src/AppBundle/*' exclude: '../../src/AppBundle/{Entity,Repository,Tests}' # controllers are imported separately to make sure they're public # and have a tag that allows actions to type-hint services AppBundleController: resource: '../../src/AppBundle/Controller' public: true tags: ['controller.service_arguments']
  • 26. D I d a n s S y m f o n y > = 3 . 3 Ta g c o n t r o l l e r. s e r v i c e _ a r g u m e n t s class DefaultController extends Controller { /** * /** * @Route("/", name="homepage") * * @param Request $request * @param EntityManagerInterface $em * @param UserServiceInterface $userService * @param LoggerInterface $logger */ public function indexAction( Request $request, EntityManagerInterface $em, UserServiceInterface $userService, LoggerInterface $logger ) { } }
  • 27. R ETR OU VEZ W EBN ET Merci pour votre attention