Dependency Injection: Make your enemies fear you

Post on 15-Jan-2015

3,014 views 2 download

Tags:

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