SlideShare a Scribd company logo
dependency injection
The pattern
by Marc Morera
@BeFactory
class Carpenter	

{	

	

 public function work()	

	

 {	

	

 	

 $hammer = new Hammer();	

	

 	

 $hammer->chop();	

	

 }	

}	

!

$carpenter = new Carpenter();	

$carpenter->work();
Problems?
Let’s talk about	

responsibility
•

Any carpenter should ignore how to build a
hammer, but how to use it.	


•

The carpenter goes to a hardware store to get
some nice brown and big hammer.
•

Not testable	


•

High coupling
class Carpenter	

{	

	

 public function work(Hammer $hammer)	

	

 {	

	

 	

 $hammer->chop();	

	

 }	

}	

!

$hammer = new Hammer();	

$carpenter = new Carpenter();	

$carpenter->work($hammer);
•

So can we just have a carpenter without a
hammer?	


•

No way!	


•

A carpenter ALWAYS have a hammer.	


•

No hammer, no carpenter.
class Carpenter	

{	

	

 private $hammer;	

!

	

	

	

	


public function __construct(Hammer $hammer)	

{	

 	

	

 $this->hammer = $hammer;	

}	


!

	

	

	

	

}	


public function work()	

{	

	

 $this->hammer->chop();	

}	


!

$hammer = new Hammer();	

$carpenter = new Carpenter($hammer);	

$carpenter->work();
2 years later…
•

All carpenters are upgraded.	


•

No hammers anymore.	


•

All carpenters will use a simple small red mallet
•

We want to make sure all objects that every
carpenter will use to chop, will be suitable for
that.	


•

How can ensure this?
Interfaces
interface ToolInterface	

{	

	

 public function chop();	

}	

!

class Hammer implements ToolInterface	

{	

	

 public function chop()	

	

 {	

	

 }	

}	

!

class Mallet implements ToolInterface	

{	

	

 public function chop()	

	

 {	

	

 }	

}
class Carpenter	

{	

	

 private $tool;	

!

	

	

	

	


public function __construct(ToolInterface $tool)	

{	

 	

	

 $this->tool = $tool;	

}	


!

	

	

	

	

}	


public function work()	

{	

	

 $this->tool->chop();	

}	


!

$carpenter = new Carpenter(new Hammer);	

$carpenter = new Carpenter(new Mallet);	

$carpenter->work();
•

Very testable and easily mockable	


•

Low coupling	


•

Seems to be the best solution ever
But…
is this implementation a good one?
NO.
•

This is purely what means dependency
injection.	


•

Every dependency of an object is injected	


•

… into the constructor if is needed for the
class to be built	


•

… in a method if is just needed for this
method
Think about a full project with this code
$iron = new Iron;	

$wood = new Wood;	

$plastic = new Plastic(new Blue);	

$hammer = new Hammer($iron, $wood, $plastic);	

$paintCan = new Paint(new Red);	

$carpenter = new Carpenter($hammer, $glasses, $paintCan);	

!

$nail = new Nail($iron);	

$carpenter->work($iron);
•

Not maintainable	


•

Not scalable	


•

Responsibility of building a carpenter is now
distributed by all controllers.
Container
What container should provide?
•

Definition	


•

Customization	


•

Instantiation
•

Our container is the provider of all instances.	


•

It is therefore responsable of building them
Services
•

A service is just an instance of an object	


•

Each service must define the path of the object
( given by the namespace )	


•

Also can define how to be built ( arguments )	


•

An argument can be another service ( using @ )
services:	

	

 iron:	

	

 	

 class: Iron	

	

 wood:	

	

 	

 class: Wood	

	

 plastic:	

	

 	

 class: Plastic	

	

 hammer:	

	

 	

 class: Hammer	

	

 	

 arguments:	

	

 	

 	

 iron: @iron	

	

 	

 	

 wood: @wood	

	

 	

 	

 plastic: @plastic	

	

 carpenter:	

	

 	

 class: Carpenter	

	

 	

 arguments:	

	

 	

 	

 hammer: @hammer
$carpenter = $container->get(‘carpenter’);
Customization
•

In this example, every time a Carpenter is
requested, a new Hammer will be used.	


•

If we want to switch to a Mallet, we must change
definition.	


•

We should be able to configure it outside the
definition of the container.
services:	

	

 iron:	

	

 	

 class: Iron	

	

 wood:	

	

 	

 class: Wood	

	

 plastic:	

	

 	

 class: Plastic	

	

 hammer:	

	

 	

 class: Hammer	

	

 	

 arguments:	

	

 	

 	

 iron: @iron	

	

 	

 	

 wood: @wood	

	

 	

 	

 plastic: @plastic	

	

 carpenter:	

	

 	

 class: Carpenter	

	

 	

 arguments:	

	

 	

 	

 hammer: @hammer
Parameters

•

Any parameter should be able to be defined in
the project	


•

A parameter is used using “%” keyword.
parameters:	

	

 tool_class: Hammer	

services:	

	

 iron:	

	

 	

 class: Iron	

	

 wood:	

	

 	

 class: Wood	

	

 plastic:	

	

 	

 class: Plastic	

	

 tool:	

	

 	

 class: %tool_class%	

	

 	

 arguments:	

	

 	

 	

 iron: @iron	

	

 	

 	

 wood: @wood	

	

 	

 	

 plastic: @plastic	

	

 carpenter:	

	

 	

 class: Carpenter	

	

 	

 arguments:	

	

 	

 	

 tool: @tool
Scopes
•

Prototype. 	


•

Container. Some objects can be just reused in
every request ( an infinite paint can ) - In the
real world, a Logger or a simple Text library.
Prototype
•

One instance per container request	


•

Container just build an instance and return it	


•

It’s defined by setting scope: prototype	


•

For example, a nail
Container
•

First time, object is built and stored.	


•

From next requests, same instance is reused and
returned	


•

Saving memory ( storing objects ) and cpu ( building
them )	


•

It’s defined by setting scope: container. Default behavior
services:	

	

 paint_can:	

	

 	

 class: PaintCan	

	

 	

 scope: container	

	

 carpenter:	

	

 	

 class: Painter	

	

 	

 scope: prototype	

	

 	

 arguments:	

	

 	

 	

 paint_can: @paint_can
•

Each time a painter is requested, we’ll reuse
same paint can object since they all can share
it.
Implementations
•

Symfony2 - DependencyInjection Component	


•

Android - Dagger	


•

Objective C - Typhoon
DI Saves your life
Use it, dude!
QA?

More Related Content

PDF
When e-commerce meets Symfony
PDF
PPTX
2CPP06 - Arrays and Pointers
PPTX
From Ruby to Scala
PPT
jDays Sweden 2016
PDF
Modern C++
PDF
Function overloading
PDF
Structure on a freeform world
When e-commerce meets Symfony
2CPP06 - Arrays and Pointers
From Ruby to Scala
jDays Sweden 2016
Modern C++
Function overloading
Structure on a freeform world

Similar to Dependency injection (20)

PPTX
2CPP04 - Objects and Classes
PDF
JS Fest 2019/Autumn. Daniel Ostrovsky. Falling in love with decorators ES6/Ty...
PPT
Rapid Application Development using Ruby on Rails
PPT
Java EE Revisits Design Patterns
PPTX
Bringing nullability into existing code - dammit is not the answer.pptx
PDF
Hey! There's OCaml in my Rust!
PPTX
tick cross game
PPT
SE2016 - Java EE revisits design patterns 2016
PDF
Introduction to Ruby Programming Language
PPTX
PPTX
25csharp
PPT
Java EE revisits design patterns
PPT
Java EE revisits design patterns
PDF
C++11 Idioms @ Silicon Valley Code Camp 2012
PPT
Javascript
PPT
Cast and copy constructor Object Oriented Programming
PDF
Refactoring Workshop (Rails Pacific 2014)
PPTX
Classes, Objects and Method - Object Oriented Programming with Java
KEY
Advanced sass/compass
PDF
Type Profiler: An Analysis to guess type signatures
2CPP04 - Objects and Classes
JS Fest 2019/Autumn. Daniel Ostrovsky. Falling in love with decorators ES6/Ty...
Rapid Application Development using Ruby on Rails
Java EE Revisits Design Patterns
Bringing nullability into existing code - dammit is not the answer.pptx
Hey! There's OCaml in my Rust!
tick cross game
SE2016 - Java EE revisits design patterns 2016
Introduction to Ruby Programming Language
25csharp
Java EE revisits design patterns
Java EE revisits design patterns
C++11 Idioms @ Silicon Valley Code Camp 2012
Javascript
Cast and copy constructor Object Oriented Programming
Refactoring Workshop (Rails Pacific 2014)
Classes, Objects and Method - Object Oriented Programming with Java
Advanced sass/compass
Type Profiler: An Analysis to guess type signatures
Ad

Recently uploaded (20)

PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
A novel scalable deep ensemble learning framework for big data classification...
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
WOOl fibre morphology and structure.pdf for textiles
PDF
DP Operators-handbook-extract for the Mautical Institute
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
Zenith AI: Advanced Artificial Intelligence
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Enhancing emotion recognition model for a student engagement use case through...
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PPTX
Chapter 5: Probability Theory and Statistics
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
Approach and Philosophy of On baking technology
PDF
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
PDF
Getting Started with Data Integration: FME Form 101
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
A novel scalable deep ensemble learning framework for big data classification...
MIND Revenue Release Quarter 2 2025 Press Release
Agricultural_Statistics_at_a_Glance_2022_0.pdf
WOOl fibre morphology and structure.pdf for textiles
DP Operators-handbook-extract for the Mautical Institute
Web App vs Mobile App What Should You Build First.pdf
Zenith AI: Advanced Artificial Intelligence
Digital-Transformation-Roadmap-for-Companies.pptx
Enhancing emotion recognition model for a student engagement use case through...
gpt5_lecture_notes_comprehensive_20250812015547.pdf
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Chapter 5: Probability Theory and Statistics
Unlocking AI with Model Context Protocol (MCP)
Group 1 Presentation -Planning and Decision Making .pptx
A comparative study of natural language inference in Swahili using monolingua...
Approach and Philosophy of On baking technology
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
Getting Started with Data Integration: FME Form 101
Ad

Dependency injection

  • 3. class Carpenter { public function work() { $hammer = new Hammer(); $hammer->chop(); } } ! $carpenter = new Carpenter(); $carpenter->work();
  • 6. • Any carpenter should ignore how to build a hammer, but how to use it. • The carpenter goes to a hardware store to get some nice brown and big hammer.
  • 8. class Carpenter { public function work(Hammer $hammer) { $hammer->chop(); } } ! $hammer = new Hammer(); $carpenter = new Carpenter(); $carpenter->work($hammer);
  • 9. • So can we just have a carpenter without a hammer? • No way! • A carpenter ALWAYS have a hammer. • No hammer, no carpenter.
  • 10. class Carpenter { private $hammer; ! public function __construct(Hammer $hammer) { $this->hammer = $hammer; } ! } public function work() { $this->hammer->chop(); } ! $hammer = new Hammer(); $carpenter = new Carpenter($hammer); $carpenter->work();
  • 11. 2 years later… • All carpenters are upgraded. • No hammers anymore. • All carpenters will use a simple small red mallet
  • 12. • We want to make sure all objects that every carpenter will use to chop, will be suitable for that. • How can ensure this?
  • 14. interface ToolInterface { public function chop(); } ! class Hammer implements ToolInterface { public function chop() { } } ! class Mallet implements ToolInterface { public function chop() { } }
  • 15. class Carpenter { private $tool; ! public function __construct(ToolInterface $tool) { $this->tool = $tool; } ! } public function work() { $this->tool->chop(); } ! $carpenter = new Carpenter(new Hammer); $carpenter = new Carpenter(new Mallet); $carpenter->work();
  • 16. • Very testable and easily mockable • Low coupling • Seems to be the best solution ever
  • 18. NO.
  • 19. • This is purely what means dependency injection. • Every dependency of an object is injected • … into the constructor if is needed for the class to be built • … in a method if is just needed for this method
  • 20. Think about a full project with this code $iron = new Iron; $wood = new Wood; $plastic = new Plastic(new Blue); $hammer = new Hammer($iron, $wood, $plastic); $paintCan = new Paint(new Red); $carpenter = new Carpenter($hammer, $glasses, $paintCan); ! $nail = new Nail($iron); $carpenter->work($iron);
  • 21. • Not maintainable • Not scalable • Responsibility of building a carpenter is now distributed by all controllers.
  • 23. What container should provide? • Definition • Customization • Instantiation
  • 24. • Our container is the provider of all instances. • It is therefore responsable of building them
  • 25. Services • A service is just an instance of an object • Each service must define the path of the object ( given by the namespace ) • Also can define how to be built ( arguments ) • An argument can be another service ( using @ )
  • 26. services: iron: class: Iron wood: class: Wood plastic: class: Plastic hammer: class: Hammer arguments: iron: @iron wood: @wood plastic: @plastic carpenter: class: Carpenter arguments: hammer: @hammer
  • 28. Customization • In this example, every time a Carpenter is requested, a new Hammer will be used. • If we want to switch to a Mallet, we must change definition. • We should be able to configure it outside the definition of the container.
  • 29. services: iron: class: Iron wood: class: Wood plastic: class: Plastic hammer: class: Hammer arguments: iron: @iron wood: @wood plastic: @plastic carpenter: class: Carpenter arguments: hammer: @hammer
  • 30. Parameters • Any parameter should be able to be defined in the project • A parameter is used using “%” keyword.
  • 31. parameters: tool_class: Hammer services: iron: class: Iron wood: class: Wood plastic: class: Plastic tool: class: %tool_class% arguments: iron: @iron wood: @wood plastic: @plastic carpenter: class: Carpenter arguments: tool: @tool
  • 32. Scopes • Prototype. • Container. Some objects can be just reused in every request ( an infinite paint can ) - In the real world, a Logger or a simple Text library.
  • 33. Prototype • One instance per container request • Container just build an instance and return it • It’s defined by setting scope: prototype • For example, a nail
  • 34. Container • First time, object is built and stored. • From next requests, same instance is reused and returned • Saving memory ( storing objects ) and cpu ( building them ) • It’s defined by setting scope: container. Default behavior
  • 35. services: paint_can: class: PaintCan scope: container carpenter: class: Painter scope: prototype arguments: paint_can: @paint_can
  • 36. • Each time a painter is requested, we’ll reuse same paint can object since they all can share it.
  • 37. Implementations • Symfony2 - DependencyInjection Component • Android - Dagger • Objective C - Typhoon
  • 38. DI Saves your life Use it, dude!
  • 39. QA?