dependency injection: make your enemies fear you
DESCRIPTION
Dependency Injection, symfony's service container and how they're used already in symfony 1.TRANSCRIPT
Nashville symfony Group
Dependency Injection: Make your enemies fear you
April 6th, 2010
Ryan Weaver@weaverryan
www.sympalphp.orgwww.iostudio.com
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:
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
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.
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
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
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.
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
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
● Used by Sympal CMF to manager all core objects
● The service container then constructs each object for you when you ask for it
Nashville symfony Group April 2010
Service Container
● Event Dispatcher
● Request
● Response
● Routing
● I18N
● View Cache
● …
● Theme Manager
● Stats Tracker
You $sc->response
Response object is created. The SC passes all dependent objects to its constructor
You
sfWebResponse
Nashville symfony Group April 2010
Service Container
● Event Dispatcher
● Request
● Response
● Routing
● I18N
● …
● The SC looks to see if the response object has already been instantiated
● The SC instantiates the response object if necessary. It knows the arguments of the constructor, and passes it everything it needs
Class sfWebResponse{...public function __construct(sfEventDispatcher $dispatcher, $options = array())
Nashville symfony Group April 2010
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
Nashville symfony Group April 2010
Nashville symfony Group April 2010
Setup configurationfor the class andoptions
Instantiate the renderer using these options
The “old” setup (without a service container)
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
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
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
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
Nashville symfony Group April 2010
1
2
3
4
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
Nashville symfony Group April 2010
Define more and more services...
Nashville symfony Group April 2010
Real-World ExamplesThe dependency injection container for symfony 1 IS used on some well-known projects
● Sympal CMFhttp://www.sympalphp.org
http://github.com/sympal/sympal/blob/master/lib/util/sfSympalContext.php#L117
● Diemhttp://diem-project.org/
http://github.com/diem-project/diem/blob/master/dmCorePlugin/lib/context/dmContext.php#L121
Questions? Idea Bubbles?
Nashville symfony Group April 2010
Ryan Weaver@weaverryan
www.sympalphp.orgwww.iostudio.com