SlideShare ist ein Scribd-Unternehmen logo
1 von 54
IoC with PHP
     Chris Weldon
  Dallas TechFest 2011
Before We Begin


                                            http://bit.ly/rf1pxR


git://github.com/neraath/ioc-php-talk.git
Your Guide: Chris Weldon

•   Fightin’ Texas Aggie

•   .Net and PHP Developer

•   UNIX and Windows Sysadmin

•   Senior Consultant at Improving Enterprises

•   Contact Me: chris@chrisweldon.net
Agile, Microsoft, Open Technologies, UX
Applied Training, Coaching, Mentoring
Certified Consulting
Rural Sourcing
Recruiting Services
Before We Get to IoC...
<?php
class Authenticator {
    private $_repository;

    public function __construct() {
        $this->_repository = new DataAccessLayer();
    }

    public function authenticate($username, $password) {
        $hashedPassword = md5($password);
        $user = $this->_repository->findByUsernameAndPassword(
            $username, $hashedPassword);
        return $user === null;
    }
}
What are the problems?
What are the problems?

•   Strongly coupled to DataAccessLayer
What are the problems?

•   Strongly coupled to DataAccessLayer
                                                    Authenticator
                                                authenticate() : bool




                                                  DataAccessLayer
                                          findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool




                                                  DataAccessLayer
                                          findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool



•   How to configure DataAccessLayer?
                                                  DataAccessLayer
                                          findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool



•   How to configure DataAccessLayer?

    •
                                                  DataAccessLayer
        Let it read configs?               findByUsernameAndPassword : array
What are the problems?

•   Strongly coupled to DataAccessLayer

•
                                                    Authenticator
    Very inflexible                              authenticate() : bool



•   How to configure DataAccessLayer?

    •
                                                  DataAccessLayer
        Let it read configs?               findByUsernameAndPassword : array


•   How to test the Authenticator?
Let’s solve it


•   What are our goals?

    •   Decrease coupling

    •   Increase configurability
<?php
interface IUserRepository {
    function findByUsernameAndPassword($username, $password);
}
class DataAccessLayer implements IUserRepository {
    private $_configParams;
    private $_database;

    public function __construct(array $configParams) {
        $this->_configParams = $configParams;
        $this->_database = Zend_Db::factory('Pdo_Mysql', $this->_configParams);
    }

    public function findByUsernameAndPassword($username, $password) {
        $query = 'SELECT * FROM users WHERE username = ? AND password = ?';
        $result = $this->_database->fetchAll($query, $username, $password);
        return $result;
    }
}
Our Updated Authenticator
<?php
class Authenticator {
    private $_repository;

    public function __construct(IUserRepository $repository) {
        $this->_repository = $repository;
    }

    public function authenticate($username, $password) {
        $hashedPassword = md5($password);
        $user = $this->_repository->findByUsernameAndPassword(
            $username, $hashedPassword);
        return $user === null;
    }
}
Time to Consume
<?php
class LoginController {
    public function login($username, $password) {
        $configuration = Zend_Registry::get('dbconfig');
        $dal = new DataAccessLayer($configuration);
        $authenticator = new Authenticator($dal);
        if ($authenticator->authenticate($username, $password)) {
            // Do something to log the user in.
        }
    }
}
Goal Recap


•   What were our goals?

    •   Decrease coupling

    •   Increase configurability
Goal Recap


•   What were our goals?

    •   Decrease coupling

    •   Increase configurability
Goal Recap


•   What were our goals?

    •   Decrease coupling

    •   Increase configurability
What You Saw Was IoC
•   Inversion of Control changes direction of responsibility

    •   Someone else responsible for creating and providing my
        dependencies

    •   Most commonly applied pattern: Dependency Injection

    •   Follows Dependency Inversion Principle from SOLID

•   Culture War: IoC vs. DI vs. Naming vs. Principles vs. Ideology
Dependency Inversion


•   “High-level modules should not depend upon low level modules. They
    should depend upon abstractions.

•   “Abstractions should not depend upon details. Details should depend
    upon abstractions.”
                                                           Robert Martin
Let’s Draw
Let’s Draw

          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Let’s Draw

          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Let’s Draw
                                                  Authenticator
                                              authenticate() : bool

          Authenticator
      authenticate() : bool

                                                 IUserRepository
                                        findByUsernameAndPassword : array

        DataAccessLayer
findByUsernameAndPassword : array

                                                DataAccessLayer
                                        findByUsernameAndPassword : array
Benefit: Flexibility
<?php
class WebServiceUserRepository implements IUserRepository {
    public function findByUsernameAndPassword($username, $password) {
        // Fetch our user through JSON or SOAP
    }
}

class OAuthRepository implements IUserRepository {
    public function findByUsernameAndPassword($username, $password) {
        // Connect to your favorite OAuth provider
    }
}
Benefit: Testable
<?php
class WhenAuthenticating extends PHPUnit_Framework_TestCase {
    public function testGivenInvalidUsernameAndPasswordShouldReturnFalse() {
        $stub = $this->getMock('IUserRepository');
        $stub->expects($this->any())
             ->method('findByUsernameAndPassword')
             ->will($this->returnValue(null));

        $authenticator = new Authenticator($stub);

        $this->assertFalse($authenticator->authenticate('user', 'pass'));
    }
}
Dependency Injection

•   Now we can inject our dependencies to our consumer classes

•   Still requires some other class to be tightly coupled to both of those

•   Need a container that can help abstract the relationship between the
    interface and implementation
<?php
class UserRepositoryContainer {
    /** @return IUserRepository **/
    public function getRepository() {
        $container = new DataAccessLayer(array(
            'dsn' => 'mysql://localhost/database',
            'username' => 'user',
            'password' => 'pass'
        ));

        return $container;
    }
}

class LoginController {
    public function login($username, $password) {
        $container = new UserRepositoryContainer();
        $repository = $container->getRepository();
        $authenticator = new Authenticator($repository);
        // ...
    }
}
Container Woes

•   No uniform interface by which to access services

•   Still tightly coupled with dependencies

•   Configurability of the container difficult

•   How to auto-inject dependency for configured consumer classes?
Symfony Dependency Injection
                 Container

•   Two Ways to Setup and Use sfServiceContainer

    •   Create subclass

    •   Manual registration via code or config
sfServiceContainer Subclass

<?php
class UserRepositoryContainer extends sfServiceContainer {
    protected function getUserRepositoryService() {
        $container = new DataAccessLayer($this['repository.config']);
        return $container;
    }
}
Consuming the Container
<?php
class LoginController {
    public function login($username, $password) {
        $configuration = Zend_Registry::get('dbconfig');

        $container = new UserRepositoryContainer(array(
            'repository.config' => $configuration
        ));
        $repository = $container->userRepository;

        $authenticator = new Authenticator($repository);
        if ($authenticator->authenticate($username, $password)) {
            // Do something to log the user in.
        }
    }
}
That’s Pretty Nice

•   Configurability a lot easier

•   Uniform interface for accessing services

•   How does this scale when there are lots of dependencies?

•   Aren’t we still coupling the container to the implementation at
    compile time?
The Builder

•   Provides a uniform way of describing services, without custom
    containers

•   For each service description, we have the flexibility to configure an
    object:

    •   At instantiation (Constructor Injection)

    •   Post-instantiation (Setter/Method Injection)
How to Describe a Service

•   Code-based or Config-based

    •   Code-based allows for run-time changing of injection parameters

    •   Config-based provides a way to change parameters between
        environments with no code changes

    •   Not mutually exclusive
Code-Based Description
<?php
// Imagine this is a bootstrap file.
$configuration = Zend_Registry::get('dbconfig');

$builder = new sfServiceContainerBuilder();

$builder->register('user_repository', 'DataAccessLayer')
        ->addArgument($configuration)
        // OR ->addArgument('%repository.config%') from earlier
        ->setShared(false);

$builder->register('authenticator', 'Authenticator')
        ->addArgument(new sfServiceReference('user_repository'));

Zend_Registry::set('di_container', $builder);
Config-Based Description
<?xml version="1.0" ?>
<container xmlns="http://symfony-project.org/2.0/container">
  <parameters>
    <parameter key="user_repository.dsn">mysql://localhost/database</parameter>
    <parameter key="user_repository.username">username</parameter>
    <parameter key="user_repository.password">password</parameter>
  </parameters>
  <services>
    <service id="user_repository" class="DataAccessLayer" shared="false">
      <argument type="collection">
        <argument key="dsn">%user_repository.dsn%</argument>
        <argument key="username">%user_repository.username%</argument>
        <argument key="password">%user_repository.password%</argument>
      </argument>
    </service>
    <service id="authenticator" class="Authenticator">
      <argument type="service" id="user_repository" />
    </service>
  </services>
</container>
Loading the Config

<?php
// Imagine this is a bootstrap file.
$builder = new sfServiceContainerBuilder();

$loader = new sfServiceContainerLoaderFileXml($builder);
$loader->load('/pathTo/services.xml');

Zend_Registry::set('di_container', $builder);
Using the Container

<?php
class LoginController {
    public function login($username, $password) {
        $container = Zend_Registry::get('di_container');
        $authenticator = $container->authenticator;
        if ($authenticator->authenticate($username, $password)) {
            // Do something to log the user in.
        }
    }
}
High Level Picture
        DataAccessLayer
findByUsernameAndPassword : array




         IUserRepository
findByUsernameAndPassword : array
                                     sfServiceContainerBuilder
                                   getService : object
                                   setService : void
                                   hasService : bool
            Authenticator
authenticate() : bool




            IAuthenticator
authenticate() : bool



                                     sfServiceContainerInterface
                                   getService : object
           LoginController         setService : void
        login() : void             hasService : bool
When to Use a DI Container
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)

•   Great for resource requirements (e.g. repositories, loggers, etc.)
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)

•   Great for resource requirements (e.g. repositories, loggers, etc.)

•   Really great for plugin-type architecture
When to Use a DI Container

•   Not for model objects (e.g. Orders, Documents, etc.)

•   Great for resource requirements (e.g. repositories, loggers, etc.)

•   Really great for plugin-type architecture

•   But not necessary to use Dependency Injection!
Other Considerations
Other Considerations

•   Learning curve
Other Considerations

•   Learning curve

•   Tracking dependencies
Other Considerations

•   Learning curve

•   Tracking dependencies

•   Dependency changes
Other Considerations

•   Learning curve

•   Tracking dependencies

•   Dependency changes

•   Setter/method vs. constructor injection
Service Lifetimes


•   setShared() allows you to specify context persistence

    •   If shared, acts like a singleton

    •   Useful if construction is expensive or state persistence required
Let’s Code
Thank You!


                                            http://bit.ly/rf1pxR


git://github.com/neraath/ioc-php-talk.git

Weitere ähnliche Inhalte

Was ist angesagt?

Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Yevgeniy Brikman
 
Cloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFECloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFEPrabath Siriwardena
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScriptYakov Fain
 
Domain Driven Design using Laravel
Domain Driven Design using LaravelDomain Driven Design using Laravel
Domain Driven Design using Laravelwajrcs
 
Hibernate training
Hibernate trainingHibernate training
Hibernate trainingTechFerry
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendKarsten Thoms
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Codescidept
 
AspMVC4 start101
AspMVC4 start101AspMVC4 start101
AspMVC4 start101Rich Helton
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unitsitecrafting
 
Spring training
Spring trainingSpring training
Spring trainingTechFerry
 
Code Generation idioms with Xtend
Code Generation idioms with XtendCode Generation idioms with Xtend
Code Generation idioms with XtendHolger Schill
 
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor ExtensionsConnect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensionsstable|kernel
 
Apex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasApex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasSalesforce Developers
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
TangoWithDjango - ch8
TangoWithDjango - ch8TangoWithDjango - ch8
TangoWithDjango - ch8Asika Kuo
 

Was ist angesagt? (20)

Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Cloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFECloud Native Identity with SPIFFE
Cloud Native Identity with SPIFFE
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
Domain Driven Design using Laravel
Domain Driven Design using LaravelDomain Driven Design using Laravel
Domain Driven Design using Laravel
 
Hibernate training
Hibernate trainingHibernate training
Hibernate training
 
Data Validation models
Data Validation modelsData Validation models
Data Validation models
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
AspMVC4 start101
AspMVC4 start101AspMVC4 start101
AspMVC4 start101
 
Better Testing With PHP Unit
Better Testing With PHP UnitBetter Testing With PHP Unit
Better Testing With PHP Unit
 
Spring training
Spring trainingSpring training
Spring training
 
Code Generation idioms with Xtend
Code Generation idioms with XtendCode Generation idioms with Xtend
Code Generation idioms with Xtend
 
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor ExtensionsConnect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
Connect.Tech- Enhancing Your Workflow With Xcode Source Editor Extensions
 
Apex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasApex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and Canvas
 
ExtJs Basic Part-1
ExtJs Basic Part-1ExtJs Basic Part-1
ExtJs Basic Part-1
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Web API with ASP.NET MVC by Software development company in india
Web API with ASP.NET  MVC  by Software development company in indiaWeb API with ASP.NET  MVC  by Software development company in india
Web API with ASP.NET MVC by Software development company in india
 
TangoWithDjango - ch8
TangoWithDjango - ch8TangoWithDjango - ch8
TangoWithDjango - ch8
 
2007 Zend Con Mvc
2007 Zend Con Mvc2007 Zend Con Mvc
2007 Zend Con Mvc
 

Andere mochten auch

Ioc & in direction
Ioc & in directionIoc & in direction
Ioc & in direction育汶 郭
 
2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介xceman
 
PHP Unit-Testing With Doubles
PHP Unit-Testing With DoublesPHP Unit-Testing With Doubles
PHP Unit-Testing With DoublesMihail Irintchev
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにYuya Takeyama
 
Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations GmbH
 
PHPUnit 入門介紹
PHPUnit 入門介紹PHPUnit 入門介紹
PHPUnit 入門介紹Jace Ju
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Jmeter Performance Testing
Jmeter Performance TestingJmeter Performance Testing
Jmeter Performance TestingAtul Pant
 
Di – ioc (ninject)
Di – ioc (ninject)Di – ioc (ninject)
Di – ioc (ninject)ZealousysDev
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit TestingMike Lively
 

Andere mochten auch (12)

Ioc & in direction
Ioc & in directionIoc & in direction
Ioc & in direction
 
2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介2007 5 30 肖镜辉 统计语言模型简介
2007 5 30 肖镜辉 统计语言模型简介
 
Stub you!
Stub you!Stub you!
Stub you!
 
PHP Unit-Testing With Doubles
PHP Unit-Testing With DoublesPHP Unit-Testing With Doubles
PHP Unit-Testing With Doubles
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015
 
PHPUnit 入門介紹
PHPUnit 入門介紹PHPUnit 入門介紹
PHPUnit 入門介紹
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Jmeter Performance Testing
Jmeter Performance TestingJmeter Performance Testing
Jmeter Performance Testing
 
Di – ioc (ninject)
Di – ioc (ninject)Di – ioc (ninject)
Di – ioc (ninject)
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
 

Ähnlich wie IoC with PHP

Implementing access control with zend framework
Implementing access control with zend frameworkImplementing access control with zend framework
Implementing access control with zend frameworkGeorge Mihailov
 
Third Party Auth in WebObjects
Third Party Auth in WebObjectsThird Party Auth in WebObjects
Third Party Auth in WebObjectsWO Community
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress DeveloperJoey Kudish
 
Java EE 8 security and JSON binding API
Java EE 8 security and JSON binding APIJava EE 8 security and JSON binding API
Java EE 8 security and JSON binding APIAlex Theedom
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::ManagerJay Shirley
 
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Sirar Salih
 
10 Rules for Safer Code
10 Rules for Safer Code10 Rules for Safer Code
10 Rules for Safer CodeQuang Ngoc
 
Persistant Cookies and LDAP Injection
Persistant Cookies and LDAP InjectionPersistant Cookies and LDAP Injection
Persistant Cookies and LDAP InjectionMaulikLakhani
 
10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]Olivier Dony
 
Simple Web Development in Java
Simple Web Development in JavaSimple Web Development in Java
Simple Web Development in JavaVincent Tencé
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyPaweł Tekliński
 
Security in laravel
Security in laravelSecurity in laravel
Security in laravelSayed Ahmed
 
Code your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard LearnCode your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard LearnDan Rinzel
 
State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8OPEN KNOWLEDGE GmbH
 
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8OPEN KNOWLEDGE GmbH
 
Authentication with zend framework
Authentication with zend frameworkAuthentication with zend framework
Authentication with zend frameworkGeorge Mihailov
 
devise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwandevise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwanTse-Ching Ho
 

Ähnlich wie IoC with PHP (20)

Implementing access control with zend framework
Implementing access control with zend frameworkImplementing access control with zend framework
Implementing access control with zend framework
 
Third Party Auth in WebObjects
Third Party Auth in WebObjectsThird Party Auth in WebObjects
Third Party Auth in WebObjects
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress Developer
 
Java EE 8 security and JSON binding API
Java EE 8 security and JSON binding APIJava EE 8 security and JSON binding API
Java EE 8 security and JSON binding API
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
 
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
Azure Table Storage: The Good, the Bad, the Ugly (15 min. lightning talk)
 
10 Rules for Safer Code
10 Rules for Safer Code10 Rules for Safer Code
10 Rules for Safer Code
 
Persistant Cookies and LDAP Injection
Persistant Cookies and LDAP InjectionPersistant Cookies and LDAP Injection
Persistant Cookies and LDAP Injection
 
10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]10 Rules for Safer Code [Odoo Experience 2016]
10 Rules for Safer Code [Odoo Experience 2016]
 
Simple Web Development in Java
Simple Web Development in JavaSimple Web Development in Java
Simple Web Development in Java
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testy
 
Security in laravel
Security in laravelSecurity in laravel
Security in laravel
 
Code your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard LearnCode your Own: Authentication Provider for Blackboard Learn
Code your Own: Authentication Provider for Blackboard Learn
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8State of the art authentication mit Java EE 8
State of the art authentication mit Java EE 8
 
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
STATE OF THE ART AUTHENTICATION MIT JAVA EE 8
 
Phactory
PhactoryPhactory
Phactory
 
Authentication with zend framework
Authentication with zend frameworkAuthentication with zend framework
Authentication with zend framework
 
Javascript Php Crud
Javascript Php CrudJavascript Php Crud
Javascript Php Crud
 
devise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwandevise tutorial - 2011 rubyconf taiwan
devise tutorial - 2011 rubyconf taiwan
 

Mehr von Chris Weldon

REST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkREST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkChris Weldon
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareChris Weldon
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietyChris Weldon
 
Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Chris Weldon
 

Mehr von Chris Weldon (7)

Keat presentation
Keat presentationKeat presentation
Keat presentation
 
REST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkREST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend Framework
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver Software
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010
 
PHP & MVC
PHP & MVCPHP & MVC
PHP & MVC
 

Kürzlich hochgeladen

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 

Kürzlich hochgeladen (20)

Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 

IoC with PHP

  • 1. IoC with PHP Chris Weldon Dallas TechFest 2011
  • 2. Before We Begin http://bit.ly/rf1pxR git://github.com/neraath/ioc-php-talk.git
  • 3. Your Guide: Chris Weldon • Fightin’ Texas Aggie • .Net and PHP Developer • UNIX and Windows Sysadmin • Senior Consultant at Improving Enterprises • Contact Me: chris@chrisweldon.net
  • 4. Agile, Microsoft, Open Technologies, UX Applied Training, Coaching, Mentoring Certified Consulting Rural Sourcing Recruiting Services
  • 5. Before We Get to IoC... <?php class Authenticator { private $_repository; public function __construct() { $this->_repository = new DataAccessLayer(); } public function authenticate($username, $password) { $hashedPassword = md5($password); $user = $this->_repository->findByUsernameAndPassword( $username, $hashedPassword); return $user === null; } }
  • 6. What are the problems?
  • 7. What are the problems? • Strongly coupled to DataAccessLayer
  • 8. What are the problems? • Strongly coupled to DataAccessLayer Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 9. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 10. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool • How to configure DataAccessLayer? DataAccessLayer findByUsernameAndPassword : array
  • 11. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool • How to configure DataAccessLayer? • DataAccessLayer Let it read configs? findByUsernameAndPassword : array
  • 12. What are the problems? • Strongly coupled to DataAccessLayer • Authenticator Very inflexible authenticate() : bool • How to configure DataAccessLayer? • DataAccessLayer Let it read configs? findByUsernameAndPassword : array • How to test the Authenticator?
  • 13. Let’s solve it • What are our goals? • Decrease coupling • Increase configurability
  • 14. <?php interface IUserRepository { function findByUsernameAndPassword($username, $password); } class DataAccessLayer implements IUserRepository { private $_configParams; private $_database; public function __construct(array $configParams) { $this->_configParams = $configParams; $this->_database = Zend_Db::factory('Pdo_Mysql', $this->_configParams); } public function findByUsernameAndPassword($username, $password) { $query = 'SELECT * FROM users WHERE username = ? AND password = ?'; $result = $this->_database->fetchAll($query, $username, $password); return $result; } }
  • 15. Our Updated Authenticator <?php class Authenticator { private $_repository; public function __construct(IUserRepository $repository) { $this->_repository = $repository; } public function authenticate($username, $password) { $hashedPassword = md5($password); $user = $this->_repository->findByUsernameAndPassword( $username, $hashedPassword); return $user === null; } }
  • 16. Time to Consume <?php class LoginController { public function login($username, $password) { $configuration = Zend_Registry::get('dbconfig'); $dal = new DataAccessLayer($configuration); $authenticator = new Authenticator($dal); if ($authenticator->authenticate($username, $password)) { // Do something to log the user in. } } }
  • 17. Goal Recap • What were our goals? • Decrease coupling • Increase configurability
  • 18. Goal Recap • What were our goals? • Decrease coupling • Increase configurability
  • 19. Goal Recap • What were our goals? • Decrease coupling • Increase configurability
  • 20. What You Saw Was IoC • Inversion of Control changes direction of responsibility • Someone else responsible for creating and providing my dependencies • Most commonly applied pattern: Dependency Injection • Follows Dependency Inversion Principle from SOLID • Culture War: IoC vs. DI vs. Naming vs. Principles vs. Ideology
  • 21. Dependency Inversion • “High-level modules should not depend upon low level modules. They should depend upon abstractions. • “Abstractions should not depend upon details. Details should depend upon abstractions.” Robert Martin
  • 23. Let’s Draw Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 24. Let’s Draw Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 25. Let’s Draw Authenticator authenticate() : bool Authenticator authenticate() : bool IUserRepository findByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array
  • 26. Benefit: Flexibility <?php class WebServiceUserRepository implements IUserRepository { public function findByUsernameAndPassword($username, $password) { // Fetch our user through JSON or SOAP } } class OAuthRepository implements IUserRepository { public function findByUsernameAndPassword($username, $password) { // Connect to your favorite OAuth provider } }
  • 27. Benefit: Testable <?php class WhenAuthenticating extends PHPUnit_Framework_TestCase { public function testGivenInvalidUsernameAndPasswordShouldReturnFalse() { $stub = $this->getMock('IUserRepository'); $stub->expects($this->any()) ->method('findByUsernameAndPassword') ->will($this->returnValue(null)); $authenticator = new Authenticator($stub); $this->assertFalse($authenticator->authenticate('user', 'pass')); } }
  • 28. Dependency Injection • Now we can inject our dependencies to our consumer classes • Still requires some other class to be tightly coupled to both of those • Need a container that can help abstract the relationship between the interface and implementation
  • 29. <?php class UserRepositoryContainer { /** @return IUserRepository **/ public function getRepository() { $container = new DataAccessLayer(array( 'dsn' => 'mysql://localhost/database', 'username' => 'user', 'password' => 'pass' )); return $container; } } class LoginController { public function login($username, $password) { $container = new UserRepositoryContainer(); $repository = $container->getRepository(); $authenticator = new Authenticator($repository); // ... } }
  • 30. Container Woes • No uniform interface by which to access services • Still tightly coupled with dependencies • Configurability of the container difficult • How to auto-inject dependency for configured consumer classes?
  • 31. Symfony Dependency Injection Container • Two Ways to Setup and Use sfServiceContainer • Create subclass • Manual registration via code or config
  • 32. sfServiceContainer Subclass <?php class UserRepositoryContainer extends sfServiceContainer { protected function getUserRepositoryService() { $container = new DataAccessLayer($this['repository.config']); return $container; } }
  • 33. Consuming the Container <?php class LoginController { public function login($username, $password) { $configuration = Zend_Registry::get('dbconfig'); $container = new UserRepositoryContainer(array( 'repository.config' => $configuration )); $repository = $container->userRepository; $authenticator = new Authenticator($repository); if ($authenticator->authenticate($username, $password)) { // Do something to log the user in. } } }
  • 34. That’s Pretty Nice • Configurability a lot easier • Uniform interface for accessing services • How does this scale when there are lots of dependencies? • Aren’t we still coupling the container to the implementation at compile time?
  • 35. The Builder • Provides a uniform way of describing services, without custom containers • For each service description, we have the flexibility to configure an object: • At instantiation (Constructor Injection) • Post-instantiation (Setter/Method Injection)
  • 36. How to Describe a Service • Code-based or Config-based • Code-based allows for run-time changing of injection parameters • Config-based provides a way to change parameters between environments with no code changes • Not mutually exclusive
  • 37. Code-Based Description <?php // Imagine this is a bootstrap file. $configuration = Zend_Registry::get('dbconfig'); $builder = new sfServiceContainerBuilder(); $builder->register('user_repository', 'DataAccessLayer') ->addArgument($configuration) // OR ->addArgument('%repository.config%') from earlier ->setShared(false); $builder->register('authenticator', 'Authenticator') ->addArgument(new sfServiceReference('user_repository')); Zend_Registry::set('di_container', $builder);
  • 38. Config-Based Description <?xml version="1.0" ?> <container xmlns="http://symfony-project.org/2.0/container"> <parameters> <parameter key="user_repository.dsn">mysql://localhost/database</parameter> <parameter key="user_repository.username">username</parameter> <parameter key="user_repository.password">password</parameter> </parameters> <services> <service id="user_repository" class="DataAccessLayer" shared="false"> <argument type="collection"> <argument key="dsn">%user_repository.dsn%</argument> <argument key="username">%user_repository.username%</argument> <argument key="password">%user_repository.password%</argument> </argument> </service> <service id="authenticator" class="Authenticator"> <argument type="service" id="user_repository" /> </service> </services> </container>
  • 39. Loading the Config <?php // Imagine this is a bootstrap file. $builder = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileXml($builder); $loader->load('/pathTo/services.xml'); Zend_Registry::set('di_container', $builder);
  • 40. Using the Container <?php class LoginController { public function login($username, $password) { $container = Zend_Registry::get('di_container'); $authenticator = $container->authenticator; if ($authenticator->authenticate($username, $password)) { // Do something to log the user in. } } }
  • 41. High Level Picture DataAccessLayer findByUsernameAndPassword : array IUserRepository findByUsernameAndPassword : array sfServiceContainerBuilder getService : object setService : void hasService : bool Authenticator authenticate() : bool IAuthenticator authenticate() : bool sfServiceContainerInterface getService : object LoginController setService : void login() : void hasService : bool
  • 42. When to Use a DI Container
  • 43. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.)
  • 44. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.) • Great for resource requirements (e.g. repositories, loggers, etc.)
  • 45. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.) • Great for resource requirements (e.g. repositories, loggers, etc.) • Really great for plugin-type architecture
  • 46. When to Use a DI Container • Not for model objects (e.g. Orders, Documents, etc.) • Great for resource requirements (e.g. repositories, loggers, etc.) • Really great for plugin-type architecture • But not necessary to use Dependency Injection!
  • 48. Other Considerations • Learning curve
  • 49. Other Considerations • Learning curve • Tracking dependencies
  • 50. Other Considerations • Learning curve • Tracking dependencies • Dependency changes
  • 51. Other Considerations • Learning curve • Tracking dependencies • Dependency changes • Setter/method vs. constructor injection
  • 52. Service Lifetimes • setShared() allows you to specify context persistence • If shared, acts like a singleton • Useful if construction is expensive or state persistence required
  • 54. Thank You! http://bit.ly/rf1pxR git://github.com/neraath/ioc-php-talk.git

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n