The document discusses dependency injection and how to implement it using a container. It describes how a container can be used to define services and their dependencies, allow for customization through parameters, and support different object scopes like prototype and container. Implementing dependency injection with a container helps increase testability, reduce coupling between classes, and make the application more maintainable and scalable.
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
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);
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 @ )
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.
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