1. Nashville symfony Group
Dependency Injection: Make your
enemies fear you
April 6th, 2010
Ryan Weaver
@weaverryan
www.sympalphp.org
www.iostudio.com
2. Nashville symfony Group April 2010
What is Dependency Injection (DI)?
● First, let's show examples of what DI is NOT
● Rewind 5 years – hopefully :) - to this code:
3. Nashville symfony Group April 2010
Where the heck did $renderAbsolute come from?
Pray to God that it's defined...
And that it's set to a meaningful value
4. Nashville symfony Group April 2010
Better, but still not Dependency Injection
But, who's in control?
The image_tag() function grabs a value it needs from
the global scope. It's not wrong, but not quite DI.
5. Nashville symfony Group April 2010
Take Control of your code (simple DI)
● You are the authoritarian leader of your app
● The method depends on you for everything
6. Nashville symfony Group April 2010
It's all about Control
● When using globals or statics, the method
depends on the global environment
● Dependency injection simply means that you
pass to your method EVERYTHING it needs,
and don't allow it to fetch variables globally
7. Nashville symfony Group April 2010
The greater the control you exhibit over the
input to your methods, the more independent,
and decoupled your objects become.
8. Nashville symfony Group April 2010
Services Container
● A “service container” is the iron fist behind a
tightly controlled group of objects
● A service container is a special class that helps
you instantiate your services (objects) and pass
in the correct dependencies.
● Instead of constructing objects, it does it for you
9. Nashville symfony Group April 2010
Symfony's Dependency Injection Component
(also known as the “service container” component)
●Allows you to define all of your services in YAML,
XML or PHP
● For each service (object), you define
● Class name
● Arguments to pass to the constructor
●The service container then constructs each object for
you when you ask for it
● Used by Sympal CMF to manager all core objects
10. Nashville symfony Group April 2010
Service Container
You $sc->response ● Event Dispatcher
● Request
● Response
Response object is created. The ● Routing
SC passes all dependent objects ● I18N
to its constructor
● View Cache
sfWebResponse ● …
● Theme Manager
You ● Stats Tracker
11. Nashville symfony Group April 2010
●The SC looks to see if the response Service Container
object has already been instantiated ● Event Dispatcher
●The SC instantiates the response ● Request
object if necessary. It knows the ● Response
arguments of the constructor, and ● Routing
passes it everything it needs
● I18N
● …
Class sfWebResponse
{
...
public function __construct(sfEventDispatcher $dispatcher, $options = array())
13. Nashville symfony Group April 2010
Example: A gallery plugin
● Create a service container that houses all of
symfony's core classes (factories)
● Create a service that renders galleries
● Allow the end user to override the gallery service
class to make customizations
15. Nashville symfony Group April 2010
The “old” setup (without a service container)
Setup configuration
for the class and
options
Instantiate the renderer using these options
16. Nashville symfony Group April 2010
Use a service container instead
● Define your services and their dependencies
● This can be done in yaml, xml or php
17. Nashville symfony Group April 2010
● The service container creates the gallery_renderer
service for you
● No service is ever created until it is asked for
● This is one of the keys behind Symfony 2's speed
18. Nashville symfony Group April 2010
Creating the Service Container
● In Symfony 2, the core classes (called factories in
symfony 1) will all be loaded through a service
container.
● Defining a new service (e.g. in YAML) is enough to
make it available in the main service container
19. Nashville symfony Group April 2010
Creating the Service Container
● In symfony 1, we'll need to setup a service container
if we want to use one.
● To make it worth a damn, we'll add symfony's core
factories to the service container so that any new
services can access them
21. Nashville symfony Group April 2010
1. Register the autoloader
2. Instantiate the service container
3. Load the services from YAML
4. Add the symfony factories to the container
The service container has everything it needs to
instantiate our “gallery_renderer” service
$renderer = $sc->gallery_renderer
23. Nashville symfony Group April 2010
Real-World Examples
The dependency injection container for symfony
1 IS used on some well-known projects
● Sympal CMF
http://www.sympalphp.org
http://github.com/sympal/sympal/blob/master/lib/util/sf
SympalContext.php#L117
● Diem
http://diem-project.org/
http://github.com/diem-
project/diem/blob/master/dmCorePlugin/lib/context/dm
Context.php#L121
24. Nashville symfony Group April 2010
Questions? Idea Bubbles?
Ryan Weaver
@weaverryan
www.sympalphp.org
www.iostudio.com