Dependency Injection Zendcon 2010 101104172213 Phpapp01

Embed Size (px)

Citation preview

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    1/103

    Dependency Injection

    Fabien Potencier

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    2/103

    Fabien Potencier

    Serial entrepreneurDeveloper by passion

    Founder of Sensio

    Creator and lead developer of Symfony

    On Twitter @fabpot

    On github http://www.github.com/fabpotBlog http://fabien.potencier.org/

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    3/103

    Dependency Injection

    A real world web example

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    4/103

    In most web applications, you need to manage the user preferences

    The user language Whether the user is authenticated or not The user credentials

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    5/103

    This can be done with a User object

    setLanguage(), getLanguage()setAuthenticated(), isAuthenticated()addCredential(), hasCredential()...

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    6/103

    The User informationneed to be persisted

    between HTTP requests

    We use the PHP session for the Storage

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    7/103

    class SessionStorage{

    function __construct($cookieName = 'PHP_SESS_ID'){

    session_name($cookieName);session_start();

    }

    function set($key, $value){

    $_SESSION[$key] = $value;}

    // ...}

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    8/103

    class User{

    protected $storage;

    function __construct(){

    $this->storage = new SessionStorage();}

    function setLanguage($language){

    $this->storage->set('language', $language);}

    // ...}

    $user = new User();

    Veryeasytouse

    Veryhardto

    customize

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    9/103

    class User{

    protected $storage;

    function __construct($storage){

    $this->storage = $storage;}

    }

    $storage = new SessionStorage();

    $user = new User($storage);Slightlymore

    difficulttouse

    Veryeasyto

    customize

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    10/103

    Thats Dependency Injection

    Nothing more

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    11/103

    Lets understand why the first example

    is not a good idea

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    12/103

    I want to change the session cookie name

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    13/103

    class User{

    protected $storage;

    function __construct(){

    $this->storage = new SessionStorage('SESSION_ID');}

    function setLanguage($language){$this->storage->set('language', $language);

    }

    // ...}

    $user = new User();

    Hardcodeitinthe

    Userclass

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    14/103

    class User{

    protected $storage;

    function __construct(){

    $this->storage = new SessionStorage(STORAGE_SESSION_NAME);}

    }

    define('STORAGE_SESSION_NAME', 'SESSION_ID');

    $user = new User();

    Addaglobal

    configuration?

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    15/103

    class User{

    protected $storage;

    function __construct($sessionName){

    $this->storage = new SessionStorage($sessionName);}

    }

    $user = new User('SESSION_ID');

    ConfigureviaUser?

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    16/103

    class User

    {protected $storage;

    function __construct($storageOptions){

    $this->storage = new SessionStorage($storageOptions['session_name']);

    $user = new User(array('session_name' => 'SESSION_ID')

    ); Configurewithanarray?

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    17/103

    I want to change the session storage implementation

    Filesystem

    MySQLMemcached

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    18/103

    class User{

    protected $storage;

    function __construct(){

    $this->storage = Registry::get('session_storage');

    }}

    $storage = new SessionStorage();Registry::set('session_storage', $storage);

    $user = new User();

    Useaglobal

    registryobject?

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    19/103

    Now, the User depends on the Registry

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    20/103

    Instead of harcoding

    the Storage dependency

    inside the User class constructor

    Inject the Storage dependency

    in the User object

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    21/103

    class User

    {protected $storage;

    function __construct($storage){

    $this->storage = $storage;}}

    $storage = new SessionStorage('SESSION_ID');$user = new User($storage);

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    22/103

    What are the advantages?

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    23/103

    Use different Storage strategies

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    24/103

    class User

    { protected $storage;

    function __construct($storage){

    $this->storage = $storage;}}

    $storage = new MySQLSessionStorage('SESSION_ID');$user = new User($storage);

    Useadifferent

    Storageengine

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    25/103

    Configuration becomes natural

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    26/103

    class User

    { protected $storage;

    function __construct($storage){

    $this->storage = $storage;}}

    $storage = new MySQLSessionStorage('SESSION_ID');$user = new User($storage);

    Configuration

    isnatural

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    27/103

    Wrap third-party classes (Interface / Adapter)

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    28/103

    class User{

    protected $storage;

    function __construct(SessionStorageInterface $storage){

    $this->storage = $storage;}

    }

    interface SessionStorageInterface{

    function get($key);

    function set($key, $value);}

    Addaninterface

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    29/103

    Mock the Storage object (for testing)

    class User{

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    30/103

    {protected $storage;

    function __construct(SessionStorageInterface $storage)

    {$this->storage = $storage;

    }}

    class SessionStorageForTests implements SessionStorageInterface{

    protected $data = array();

    static function set($key, $value)

    {self::$data[$key] = $value;

    }}

    MocktheSession

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    31/103

    Use different Storage strategies

    Configuration becomes natural

    Wrap third-party classes (Interface / Adapter)

    Mock the Storage object (for testing)

    Easy without changing the User class

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    32/103

    Dependency Injection is where

    components are given their dependencies

    through their constructors, methods, ordirectly into fields.

    http://www.picocontainer.org/injection.html

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    33/103

    $storage = new SessionStorage();

    // constructor injection$user = new User($storage);

    // setter injection

    $user = new User();$user->setStorage($storage);

    // property injection

    $user = new User();$user->storage = $storage;

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    34/103

    A slightly more complex

    web example

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    35/103

    class Application{

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    36/103

    {function __construct(){

    $this->request = new WebRequest();

    $this->response = new WebResponse();

    $storage = new FileSessionStorage('SESSION_ID');$this->user = new User($storage);

    $cache = new FileCache(array('dir' => dirname(__FILE__).'/cache')

    );$this->routing = new Routing($cache);

    }

    }

    $application = new Application();

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    37/103

    Back to square 1

    class Application{

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    38/103

    {function __construct(){

    $this->request = new WebRequest();

    $this->response = new WebResponse();

    $storage = new FileSessionStorage('SESSION_ID');$this->user = new User($storage);

    $cache = new FileCache(array('dir' => dirname(__FILE__).'/cache')

    );$this->routing = new Routing($cache);

    }

    }

    $application = new Application();

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    39/103

    We need a Container

    Describes objects

    and their dependencies

    Instantiates and configures

    objects on-demand

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    40/103

    A container

    SHOULD be able to manage

    ANY PHP object (POPO)

    The objects MUST not know

    that they are managed

    by a container

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    41/103

    Parameters The SessionStorageInterface implementation we want to use (the class name) The session name

    Objects SessionStorage User

    Dependencies User depends on a SessionStorageInterface implementation

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    42/103

    Lets build a simple container with PHP 5.3

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    43/103

    DI Container

    Managing parameters

    class Container

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    44/103

    class Container{

    protected $parameters = array();

    public function setParameter($key, $value){

    $this->parameters[$key] = $value;

    }

    public function getParameter($key){

    return $this->parameters[$key];}

    }

    Decoupling

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    45/103

    $container = new Container();$container->setParameter('session_name', 'SESSION_ID');$container->setParameter('storage_class', 'SessionStorage');

    $class = $container->getParameter('storage_class');$sessionStorage = new $class($container->getParameter('session_name'));

    $user = new User($sessionStorage);

    Decoup g

    Customization

    Objectscreation

    class Container Using PHP

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    46/103

    class Container{

    protected $parameters = array();

    public function __set($key, $value){

    $this->parameters[$key] = $value;

    }

    public function __get($key){

    return $this->parameters[$key];}

    }

    UsingPHP

    magicmethods

    Interface

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    47/103

    $container = new Container();$container->session_name = 'SESSION_ID';$container->storage_class = 'SessionStorage';

    $sessionStorage = new $container->storage_class($container->session_name);$user = new User($sessionStorage);

    Int

    iscleaner

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    48/103

    DI Container

    Managing objects

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    49/103

    We need a way to describe how to create objects,

    without actually instantiating anything!

    Anonymous functions to the rescue!

    Anonymous Functions / Lambdas

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    50/103

    y

    A lambda is a function

    defined on the fly

    with no name

    function () { echo 'Hello world!'; };

    Anonymous Functions / Lambdas

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    51/103

    y

    A lambda can be stored

    in a variable

    $hello = function () { echo 'Hello world!'; };

    Anonymous Functions / Lambdas

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    52/103

    y

    And then it can be used

    as any other PHP callable

    $hello();

    call_user_func($hello);

    Anonymous Functions / Lambdas

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    53/103

    y

    You can also pass a lambda

    as an argument to a function or method

    function foo(Closure $func){$func();

    }

    foo($hello);

    Fonctions anonymes

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    54/103

    y$hello = function ($name) { echo 'Hello '.$name; };

    $hello('Fabien');

    call_user_func($hello, 'Fabien');

    function foo(Closure $func, $name){

    $func($name);}

    foo($hello, 'Fabien');

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    55/103

    DI Container

    Managing objects

    class Container{protected $parameters = array();protected $objects array();

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    56/103

    protected $objects = array();

    public function __set($key, $value){

    $this->parameters[$key] = $value;}

    public function __get($key){

    return $this->parameters[$key];

    }

    public function setService($key, Closure $service){

    $this->objects[$key] = $service;}

    public function getService($key){

    return $this->objects[$key]($this);}

    }

    Storealambda

    abletocreatethe

    objecton-demand

    Asktheclosuretocreatetheobjectandpassthe

    currentContainer

    $container = new Container();$container >session name = 'SESSION ID';

    Description

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    57/103

    $container->session_name = SESSION_ID ;$container->storage_class = 'SessionStorage';$container->setService('user', function ($c)

    {return new User($c->getService('storage'));

    });$container->setService('storage', function ($c){

    return new $c->storage_class($c->session_name);});

    $user = $container->getService('user');

    CreatingtheUserisnowaseasyasbefore

    Descrip

    class Container{

    protected $values array(); Simplifythecode

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    58/103

    protected $values = array();

    function __set($id, $value)

    { $this->values[$id] = $value;}

    function __get($id){

    if (is_callable($this->values[$id])){

    return $this->values[$id]($this);}else{

    return $this->values[$id];}

    }}

    Simplify

    $container = new Container();$container >session name = 'SESSION ID';

    Unifiedinterface

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    59/103

    $container->session_name = SESSION_ID ;$container->storage_class = 'SessionStorage';$container->user = function ($c){

    return new User($c->storage);};$container->storage = function ($c)

    {return new $c->storage_class($c->session_name);

    };

    $user = $container->user;

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    60/103

    DI Container

    Scope

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    61/103

    For some objects, like the user,

    the container must alwaysreturn the same instance

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    62/103

    spl_object_hash($container->user)

    !==spl_object_hash($container->user)

    $container->user = function ($c)

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    63/103

    $container->user = function ($c){

    static $user;

    if (is_null($user)){

    $user = new User($c->storage);}

    return $user;};

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    64/103

    spl_object_hash($container->user)

    ===spl_object_hash($container->user)

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    65/103

    $container->user = $container->asShared(function ($c){

    return new User($c->storage);});

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    66/103

    A closure is a lambda

    that remembers the contextof its creation

    class Article{

    ( )

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    67/103

    public function __construct($title){

    $this->title = $title;}

    public function getTitle(){

    return $this->title;}

    }

    $articles = array(new Article('Title 1'),new Article('Title 2'),

    );

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    68/103

    $mapper = function ($article){

    return $article->getTitle();

    };

    $titles = array_map($mapper, $articles);

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    69/103

    $method = 'getTitle';

    $mapper = function ($article) use($method){

    return $article->$method();

    };

    $method = 'getAuthor';

    $titles = array_map($mapper, $articles);

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    70/103

    $mapper = function ($method){

    return function ($article) use($method){

    return $article->$method();};

    };

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    71/103

    $titles = array_map($mapper('getTitle'), $articles);

    $authors = array_map($mapper('getAuthor'), $articles);

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    72/103

    $container->user = $container->asShared(function ($c){

    return new User($c->storage);});

    function asShared(Closure $lambda){

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    73/103

    return function ($container) use ($lambda)

    {static $object;

    if (is_null($object)){

    $object = $lambda($container);}

    return $object;};}

    class Container{protected $values = array();

    function set($id $value)

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    74/103

    function __set($id, $value){

    $this->values[$id] = $value;

    }

    function __get($id){

    if (!isset($this->values[$id])){

    throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));

    }

    if (is_callable($this->values[$id])){

    return $this->values[$id]($this);}else{

    return $this->values[$id];}

    }}

    Errormanagement

    class Container

    {protected $values = array();

    function __set($id, $value){

    $this->values[$id] = $value;

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    75/103

    }

    function __get($id){

    if (!isset($this->values[$id])){throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));

    }

    if (is_callable($this->values[$id])){

    return $this->values[$id]($this);}else{

    return $this->values[$id];}

    }

    function asShared($callable){

    return function ($c) use ($callable){

    static $object;

    if (is_null($object)){

    $object = $callable($c);}return $object;

    };}

    }

    40LOCforafully-

    featuredcontainer

    Im NOT advocating

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    76/103

    g

    the usage of lambdas everywhere

    This presentation is about

    showing how they work

    on practical examples

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    77/103

    A DI Container

    does NOT manage

    ALL your objects

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    78/103

    Good rule of thumb:It manages Global objects

    Objects with only one instance (!= Singletons)

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    79/103

    LIKE

    a User, a Request,

    a database Connection, a Logger,

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    80/103

    UNLIKE

    Model objects (a Product, a blog Post, )

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    81/103

    Symfony Components

    Dependency Injection

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    82/103

    Rock-solid implementation of a DIC in PHP 5.3

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    83/103

    At the core of the Symfony 2.0 framework

    which is one of the fastest framework

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    84/103

    Very flexible

    Configuration in PHP, XML, YAML, or INI

    $container = new Builder();

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    85/103

    $container = new Builder();

    $container->register('output', 'FancyOutput');$container->

    register('message', 'Message')->setArguments(array(

    new sfServiceReference('output'),array('with_newline' => true)

    ));

    $container->message->say('Hello World!');

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    86/103

    services:output: { class: FancyOutput }message:

    class: Message

    arguments:- @output- { with_newline: true }

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    87/103

    true

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    88/103

    imports:- { resource: parameters.yml }- { resource: parameters.ini }- { resource: services.xml }

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    89/103

    As fast as it can be

    The container can be

    compiled down

    to plain PHP code

    use Symfony\Components\DependencyInjection\Container;use Symfony\Components\DependencyInjection\Reference;use Symfony\Components\DependencyInjection\Parameter;

    class ProjectServiceContainer extends Container{

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    90/103

    {protected $shared = array();

    protected function getOutputService(){

    if (isset($this->shared['output'])) return $this->shared['output'];

    $instance = new FancyOutput();

    return $this->shared['output'] = $instance;}

    protected function getMessageService(){

    if (isset($this->shared['message'])) return $this->shared['message'];

    $instance = new Message($this->getOutputService(), array('with_newline' => true));

    return $this->shared['message'] = $instance;}

    }

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    91/103

    Semantic configuration

    Thanks to an extension mechanism

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    92/103

    p y y p j g

    fabien.potencierxxxxxx

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    93/103

    xmlns:doctrine="http://www.symfony-project.org/schema/dic/doctrine" xmlns:zend="http://www.symfony-project.org/schema/dic/zend"

    xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd

    http://www.symfony-project.org/schema/dic/doctrine http://www.symfony-project.org/schema/dic/doctrine/doctrine-1.0.xsd

    http://www.symfony-project.org/schema/dic/swiftmailer http://www.symfony-project.org/schema/dic/swiftmailer/swiftmailer-1.0.xsd" >

    fabien.potencierxxxxxx

    auto-completion

    andvalidation

    withXSD

    zend.logger:level: debug

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    94/103

    level: debug

    path: %kernel.root_dir%/logs/%kernel.environment%.log

    doctrine.dbal:dbname: dbnameusername: root

    password: ~

    swift.mailer:transport: gmailusername: fabien.potencier

    password: xxxxxxx

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    95/103

    Everything is converted by the extension

    to plain services and parametersno overhead

    Loader::registerExtension(new SwiftMailerExtension());Loader::registerExtension(new DoctrineExtension());Loader::registerExtension(new ZendExtension());

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    96/103

    Loader::registerExtension(new ZendExtension());

    $loader = new XmlFileLoader(__DIR__);$config = $loader->load('services.xml');

    $container = new Builder();$container->merge($config);

    $container->mailer->...

    $dumper = new PhpDumper($container);echo $dumper->dump();

    More about Dependency Injection

    http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    97/103

    http://components.symfony-project.org/dependency-injection/ (5.2)

    http://github.com/fabpot/symfony/tree/master/src/Symfony/Components/DependencyInjection/(5.3)

    http://github.com/fabpot/pimple

    http://twittee.org/

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    98/103

    Remember, most of the time,

    you dont need a Container

    to use Dependency Injection

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    99/103

    You can start to use and benefit from

    Dependency Injection today

    by implementing it

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    100/103

    y p g

    in your projects

    by using externals librariesthat already use DI

    without the need of a container

    Symfony

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    101/103

    y y

    Zend FrameworkezComponents

    DoctrineSwift Mailer

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    102/103

    Questions?

    My slides will be available on

    slideshare.com/fabpot

    Sensio S.A.

    92 98 boulevard Victor Hugo

  • 8/2/2019 Dependency Injection Zendcon 2010 101104172213 Phpapp01

    103/103

    92-98, boulevard Victor Hugo

    92 115 Clichy CedexFRANCE

    Tl. : +33 1 40 99 80 80

    Contact

    Fabien Potencierfabien.potencier at sensio.com

    http://www.sensiolabs.com/

    http://www.symfony-project.org/

    http://fabien.potencier.org/