101
DEMYSTIFYING DEPENDENCY INJECTION CONTAINERS KAI SASSNOWSKI

KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

DEMYSTIFYING DEPENDENCY INJECTION CONTAINERS

KAI SASSNOWSKI

Page 2: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

DEPENDENCY INJECTION

Page 3: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 4: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 5: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

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

// ... }

Page 6: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

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

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

// ... }

Page 7: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

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

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 8: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

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

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 9: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 10: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 11: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 12: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$storage = new SessionStorage();

$user = new User($storage);

$user->setLanguage(‘de');

$user->getLanguage(); // => 'de'

Page 13: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

HOWEVER…

Page 14: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$svc = new ShippingService(new ProductLocator(), new PricingService(), new InventoryService(), new TrackingRepository(new ConfigProvider()), new Logger(new EmailLogger(new ConfigProvider())));

Page 15: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]
Page 16: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

CONTAINERS TO THE RESCUE!

Page 17: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$svc = $container->get(ShippingService::class);

Page 18: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

MAGIC

Page 19: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

3 STAGES OF MAGIC

Page 20: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

EUPHORIATHIS IS GREAT!

IT JUST WORKS (TM)!I’M GETTING SO MUCH DONE!

Page 21: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

PHP Fatal error: Uncaught exception 'ReflectionException' with message 'Class log does not exist' in /Users/Kai/dev/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:776 Stack trace: #0 /Users/Kai/dev/laravel/vendor/laravel/framework/

Page 22: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

DISTRUSTHOW DOES THIS WORK?IT BROKE, NOW WHAT?

WHAT IS EVEN GOING ON?

Page 23: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

DI-CONTAINERS

Page 24: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

UNDERSTANDINGIT’S NOT MAGIC

IT’S JUST ANOTHER ABSTRACTIONI KNOW WHERE TO LOOK IF THINGS BREAK

Page 25: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

IF YOU UNDERSTAND HOW THINGS WORK THEY STOP BEING MAGIC.

The guy on stage right now

Page 26: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

LET’S WRITE OUR OWN!

Page 27: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

A CONTAINER IS LIKE AN AGGREGATION OF FACTORIES.

Still the same guy

Page 28: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = []; }

Page 29: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, $concrete) { $this->bindings[$abstract] = $concrete; } }

Page 30: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; } }

Page 31: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; } }

Page 32: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; }

public function get($abstract) { return $this->bindings[$abstract]($this); } }

Page 33: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; }

public function get($abstract) { return $this->bindings[$abstract]($this); } }

Page 34: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; }

public function get($abstract) { return $this->bindings[$abstract]($this); } }

Page 35: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 36: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 37: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 38: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 39: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class SessionStorage { public function __construct() { session_start(); }

public function set($key, $value) { $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

Page 40: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 41: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 42: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 43: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 44: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 45: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 46: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class DatabaseLogger implements Logger { public function log($message) { echo "Logging $message to the database…"; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 47: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class DatabaseLogger implements Logger { public function log($message) { echo "Logging $message to the database…"; } }

class User { protected $storage;

function __construct(SessionStorage $storage) { $this->storage = $storage; }

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

function getLanguage() { return $this->storage->get('language'); }

// ... }

class SessionStorage { protected $logger;

public function __construct(Logger $logger) { session_start();

$this->logger = $logger; }

public function set($key, $value) { $this->logger->log( "Setting [$key] to [$value]” ); $_SESSION[$key] = $value; }

public function get($key) { return $_SESSION[$key]; } }

Page 48: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

Page 49: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function () { });

Page 50: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function () { return new User(); });

Page 51: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function () { return new User(???); });

Page 52: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function () { return new User( new SessionStorage( new DatabaseLogger())); });

Page 53: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function () { return new User(???); });

Page 54: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; }

public function get($abstract) { return $this->bindings[$abstract]($this); } }

Page 55: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; }

public function get($abstract) { return $this->bindings[$abstract]($this); } }

Page 56: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function () { return new User(???); });

Page 57: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User(???); });

Page 58: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

Page 59: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(Logger::class)); });

Page 60: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(Logger::class)); });

Page 61: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(Logger::class)); });

$container->set(Logger::class, function (Container $c) { return new DatabaseLogger(); });

Page 62: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(Logger::class)); });

$container->set(Logger::class, function (Container $c) { return new DatabaseLogger(); });

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 63: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

Page 64: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

Page 65: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

$container->get(SessionStorage::class)

Page 66: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

$container->get(SessionStorage::class)

function (Container $c) { return new SessionStorage($c->get(Logger::class)); }

Page 67: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

$container->get(SessionStorage::class)

function (Container $c) { return new SessionStorage($c->get(Logger::class)); }

$container->get(Logger::class)

Page 68: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

$container->get(SessionStorage::class)

function (Container $c) { return new SessionStorage($c->get(Logger::class)); }

$container->get(Logger::class)

function (Container $c) { return new DatabaseLogger(); }

Page 69: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

$container->get(SessionStorage::class)

function (Container $c) { return new SessionStorage($c->get(Logger::class)); }

DatabaseLogger();

Page 70: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

$container->get(SessionStorage::class)

function (Container $c) { return new SessionStorage(DatabaseLogger()); }

Page 71: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User($c->get(SessionStorage::class)); };

SessionStorage(DatabaseLogger())

Page 72: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container->get(User::class);

function (Container $c) { return new User(SessionStorage(DatabaseLogger())); };

Page 73: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

User(SessionStorage(DatabaseLogger()));

Page 74: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

User(SessionStorage(DatabaseLogger()));

Page 75: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

class Container { protected $bindings = [];

public function set($abstract, callable $concrete) { $this->bindings[$abstract] = $concrete; }

public function get($abstract) { return $this->bindings[$abstract]($this); } }

Page 76: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

Page 77: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

THE ABILITY OF THE CONTAINER TO AUTOMATICALLY BUILD A CLASS WITHOUT NEEDING AN EXPLICIT BINDING.

Take a guess

Page 78: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(Logger::class)); });

$container->set(Logger::class, function (Container $c) { return new DatabaseLogger(); });

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 79: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(Logger::class)); });

$container->set(Logger::class, function (Container $c) { return new DatabaseLogger(); });

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 80: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(DatabaseLogger::class)); });

$container->set(Logger::class, function (Container $c) { return new DatabaseLogger(); });

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 81: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$container->set(User::class, function (Container $c) { return new User($c->get(SessionStorage::class)); });

$container->set(SessionStorage::class, function (Container $c) { return new SessionStorage($c->get(DatabaseLogger::class)); });

$container->set(DatabaseLogger::class, function (Container $c) { return new DatabaseLogger(); });

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 82: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 83: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

REFLECTION BASED AUTOWIRING

▸ Build a ReflectionClass

▸ Build its dependencies

▸ Get the constructor

▸ Get its parameters

▸ Look at the types

▸ Recursively build the dependencies

▸ Create new instance

Page 84: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

1. BUILD A REFLECTION CLASSpublic function get($abstract) { $reflection = new ReflectionClass($abstract); }

Page 85: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2. BUILD ITS DEPENDENCIESpublic function get($abstract) { $reflection = new ReflectionClass($abstract); }

Page 86: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2. BUILD ITS DEPENDENCIESpublic function get($abstract) { $reflection = new ReflectionClass($abstract); $dependencies = $this->buildDependencies($reflection); }

Page 87: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.1. GET ITS CONSTRUCTORpublic function get($abstract) { $reflection = new ReflectionClass($abstract); $dependencies = $this->buildDependencies($reflection); }

Page 88: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.1. GET ITS CONSTRUCTORprivate function buildDependencies($reflection) { $constructor = $reflection->getConstructor(); }

Page 89: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.1. GET ITS CONSTRUCTORprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

}

Page 90: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.2. GET ITS PARAMETERSprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

}

Page 91: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.2. GET ITS PARAMETERSprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

}

Page 92: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.2. GET ITS PARAMETERSprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

return array_map(function ($param) {

}, $params);

}

Page 93: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.3. LOOK AT THE TYPESprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

return array_map(function ($param) {

}, $params);

}

Page 94: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.3. LOOK AT THE TYPESprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

return array_map(function ($param) { $type = $param->getType();

}, $params);

}

Page 95: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.3. LOOK AT THE TYPESprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

return array_map(function ($param) { if (!$type = $param->getType()) { throw new RuntimeException(); }

}, $params);

}

Page 96: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.4. RECURSIVELY BUILD THE DEPENDENCYprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

return array_map(function ($param) { if (!$type = $param->getType()) { throw new RuntimeException(); }

}, $params);

}

Page 97: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

AUTOWIRING

2.4. RECURSIVELY BUILD THE DEPENDENCYprivate function buildDependencies($reflection) { if (!$constructor = $reflection->getConstructor()) { return []; }

$params = $constructor->getParameters();

return array_map(function ($param) { if (!$type = $param->getType()) { throw new RuntimeException(); } return $this->get($type);

}, $params);

}

Page 98: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

public function get($abstract) { if (isset($this->bindings[$abstract])) { return $this->bindings[$abstract]($this); }

$reflection = new ReflectionClass($abstract); $dependencies = $this->buildDependencies($reflection);

return $reflection->newInstanceArgs($dependencies); }

Page 99: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

$container = new Container();

$user = $container->get(User::class); $user->setLanguage('de'); $user->getLanguage(); // => 'de'

Page 100: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

TL;DL RECURSION

Page 101: KAI SASSNOWSKI DEMYSTIFYING DEPENDENCY INJECTION … · class SessionStorage { public function __construct() { session_start(); } public function set($key, $value) { $_SESSION[$key]

THANKS!