Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dependency Injection

Dependency Injection

A talk on Inversion of Control, Dependency Injection, Service Locators, Dependency Injection Containers and general awesomeness.

James Mallison

March 04, 2014
Tweet

More Decks by James Mallison

Other Decks in Programming

Transcript

  1. DEPENDENCY INJECTION VS. SERVICE LOCATION DEPENDENCY INJECTION CONTAINERS Examples and

    Comparison PHP-DI Auryn FRAMEWORK INTEGRATION DEMO POPULAR FRAMEWORKS How they do it
  2. DEPENDENCY INJECTION Code is now TESTABLE (eg. with phpunit) Object

    requirements can be seen from the method signatures only
  3. SERVICE LOCATION Dependency Injection Here Actual dependencies still hidden from

    method signature (they're in this "container") MyService now tied to container But Service Location Here
  4. SERVICE LOCATION NOT A FACTORY Factories: build and return objects

    SLs: equivalent of an associative array Set objects at bootstrap Retrieve objects when requested Objects may be instantiated lazily (only when you ask for them, think via PHP 5's closures)
  5. WHY DI > SL Every object you create: • The

    public methods are an API to the object's usage • How the methods can be used should be visible from the method signatures alone Pass in your container = a container dependency, hard to test etc Pass in your object = we know exactly what the object needs to run
  6. SYMFONY 2 Complexity increases for other arguments, dependencies etc Injection

    in constructor, but may not be used by all methods (waste of resources for controllers)
  7. SILEX The whole app is a service locator... $foo contains:

    • Logging • Database • Other registered services • Let's go check the docs... (to the developer writing it)
  8. SILEX The whole app is a service locator... $foo contains:

    • Logging • Database • Other registered services • Let's go check the docs... (to the developer writing it) $foo contains: • No idea... • Let's go check the docs... (to a future developer)
  9. SILEX ServiceControllerServiceProvider Bootstrap: Define dependencies individually Bootstrap: Define controller with

    the above Controller: Typehint for your dependency Great! But still a lot just for one dependency... Still constructor-only injection
  10. SO FAR... Popular frameworks offer both Dependency Injection and Service

    Location SL = simpler, but couples service to container DI = Testable code, but time consuming to set up and configure Method requirements should be visible from the method signature only Constructor-only injection in your controllers shares objects that may not need to be shared Note: we're not talking about setter injection here Method injection in your controllers provides a clear explanation of the method's needs Controllers don't always adhere to SRP anyway
  11. DEPENDENCY INJECTION Starts most visibly at the Controller Resolution level

    Look at the controller resolver to see where you can place a DI container
  12. DEPENDENCY INJECTION Starts most visibly at the Controller Resolution level

    Look at the controller resolver to see where you can place a DI container
  13. DEPENDENCY INJECTION Starts most visibly at the Controller Resolution level

    Look at the controller resolver to see where you can place a DI container
  14. DEPENDENCY INJECTION Starts most visibly at the Controller Resolution level

    Look at the controller resolver to see where you can place a DI container Decorate existing class to maintain default functionality
  15. DI CONTAINERS Composition Root pattern Define your object graph ("wiring")

    as close to the top layer as possible ie. in your bootstrap In PHP, this could involve: Sequentially manually created objects An array of object mappings as strings A configuration file containing mappings
  16. AURYN INJECTOR Usage 1. Uses reflection to read the method

    signature of MyService 2. Sees the typehint for DatabaseObject 3. Uses reflection to read the method signature for DatabaseObject 4. No dependencies here, creates the DatabaseObject and injects it into MyService
  17. AURYN INJECTOR Usage 1. Uses reflection to read the method

    signature of MyService 2. Sees the typehint for DatabaseObject 3. Uses reflection to read the method signature for DatabaseObject 4. No dependencies here, creates the DatabaseObject and injects it into MyService Do this in your composition root Do this in your controller resolver
  18. POLYMORPHISM Runtime Polymorphism via the DiC DatabaseInterface will use "MongoDbInstead"

    concrete class When "MyService" is resolved: 1. The constructor signature will be read via reflection 2. The DatabaseInterface will be found as a dependency 3. The alias for DatabaseInterface is "MongoDbInstead" 4. The MongoDbInstead class is dependency injected for us
  19. PHP-DI VS AURYN PHP-DI AURYN Recursive DI and Caching Recursive

    DI and Caching Nice website, more in-depth docs Github-only, less support Constructor-only Injection Application-wide Injection