Introduction to DI(C)


meet.php #5    http://meetphp.pl/   19.05.2012
About me

$speaker = new Speaker;

$speaker->name            = "Radosław Benkel";
$speaker->twitter         = "@singlespl";
$speaker->blog            = "http://blog.rbenkel.me";

$speaker->givePresentation();
What?
What?


Dependency
Injection
Container
What?




Dependency
Dependency

class TwitterAPIClient
{
    protected $httpClient;
    public function __construct()
    {
        $this->httpClient = new SomeCurlWrapper();
    }

    /* ... */
}

$client = new TwitterApiClient;
Dependency
                                  This
 is
 your
 dependency.
class TwitterAPIClient
{
    protected $httpClient;
    public function __construct()
    {
        $this-httpClient = new SomeCurlWrapper();
    }

    /* ... */
}

$client = new TwitterApiClient;
Dependency



“What’s
 wrong
 with
 
      that”?
Dependency




Try testing it...
Dependency



...or change client
  implementation
Dependency
Dependency




So let’s use Injection
What?




Injection
Injection

class TwitterAPIClient
{
    protected $httpClient;
    public function __construct($httpClient)
    {
        $this-httpClient = $httpClient;
    }

    /* ... */
}                           And
 here
 you
 inject
 dependency

$client = new TwitterApiClient(new SomeCurlWrapper);
Injection




 So...
Injection
public function __construct()
{
    $this-httpClient = new SomeCurlWrapper();
}

                     VS
public function __construct($httpClient)
{
    $this-httpClient = $httpClient;
}
Injection




it’s just like...
Injection




  VS
Injection




                                                                                                                                                                VS

Try
 replacing
 battery,
 and
 you
 will
 now
 what
 I’m
 talking
 
                                                                                                                            about.
 
Injection




Injection types:
Injection

    Injection types:
•   constructor injection
Injection

    Injection types:
•   constructor injection
•   setter injection
Injection

    Injection types:
•   constructor injection
•   setter injection
•   interface injection
Injection
          Constructor injection
class TwitterAPIClient
{
    protected $httpClient;
    public function __construct($httpClient)
    {
        $this-httpClient = $httpClient;
    }

    /* ... */
}
$client = new TwitterApiClient(new SomeCurlWrapper);
Injection
                Setter injection
class TwitterAPIClient
{
    protected $httpClient;
    public function __construct() {}

    public function setHttpClient($httpClient) {
        $this-httpClient = $httpClient;
    }

    /* ... */
}
$client = new TwitterApiClient;
$client-setHttpClient(new SomeCurlWrapper);
Injection
             Interface injection
interface HttpClientInterface {
    public function setHttpClient($httpClient);
}

class TwitterAPIClient implements HttpClientInterface {
    protected $httpClient;
    public function __construct() {}
    public function setHttpClient($httpClient) {
        $this-httpClient = $httpClient;
    }
    /* ... */
}

$client = new TwitterApiClient;
$client-setHttpClient(new SomeCurlWrapper);
Injection




So far so good...
Injection



...until you don’t have
 to do something like
          that:
Injection
$mapper = new UserMapperEncrypted(
    new UserMapperCached(
        new UserMapperDB(
            new PDO(
                'mysql:host=127.0.0.1',
                'user',
                'password'
            )
        ),
        new RedisCacheAdapter(
            '127.0.0.1:6379'
        )
    ),
    'YourSuperSecretPass'
);

$mapper-save(new User('John', 'Doe'));
Injection
Injection




“How
 to
 solve
 that”?
Injection




Just use...
What?




Container
Container



require_once container_prod.php;

$mapper = $container-get('mapper.user');

/* mapper is UserMapperEncrypted, which uses UserMapperCached,
which uses UserMapperDB, which uses PDO. */
$mapper-save(new User('John', 'Doe'));
Container



require_once container_dev.php;

$mapper = $container-get('mapper.user');

/* mapper is UserMapperDB, with different PDO configuration.
*/
$mapper-save(new User('John', 'Doe'));
Container
require_once container_prod.php;
$mapper = $container-get('mapper.user');
$mapper-save(new User('John', 'Doe'));



        Find
 the
 difference

require_once container_dev.php;
$mapper = $container-get('mapper.user');
$mapper-save(new User('John', 'Doe'));
Container
require_once container_prod.php;
$mapper = $container-get('mapper.user');
$mapper-save(new User('John', 'Doe'));




require_once container_dev.php;
$mapper = $container-get('mapper.user');
$mapper-save(new User('John', 'Doe'));
Container
require_once container_prod.php;
$mapper = $container-get('mapper.user');
$mapper-save(new User('John', 'Doe'));


                                         Find

Introduction to DI(C)