A Look inside
The Illuminate Container

Ian Littman / @iansltx

Laravel Austin, March 2019

https://ian.im/LC0319

Not gonna talk about facades

They're an antipattern

...and I need to clean up some code I have that uses them...

...and on-the-fly facades are some level 70 autoloader voodoo.

Binding classes

  • bind() (or singleton() for shared classes)
    • null second param copies first param (for setting a class to be bound as a singleton)
    • bindIf() - bind if not bound
    • offsetSet($k, $v), __set() - bind(), wrap $v in a closure returning $v if it isn't a closure already
  • Contextual Binding
    • when()->needs()->give()
    • addContextualBinding($concrete, $abstract, $impl)
  • instance() - Provide an already-instantiated class as the destination of a dependency
    • forgetInstance($abstract) + forgetInstances() exist

Binding classes, Part 2

  • Binding checks
    • bound/has/offsetExists() - bindings, instances, aliases
    • resolved() - resolved, instances, aliases
    • getBindings()
  • Tags
    • tag() - assign an identifier to one or more tags
    • tagged() - iterable of resolved deps assigned to a tag
  • Aliases
    • alias() - Map a concrete class name to an interface
    • getAlias() - Returns the mapping set by alias()

Binding classes, Part 3

  • extend() - Wrap a dep in a closure($dep, $container)
    • forgetExtenders($abstract) exists
  • Rebinding
    • rebinding($abstract, $cb) - call $cb($instance, $container) any time $abstract is rebound
    • refresh($abstract, $target, $method) - call $method on $target with $instance as a param on-rebind
  • offsetUnset($k) drops from bindings/instances/resolved
  • flush() drops all bindings/aliases/resolved classes

Resolving Classes

  • make($abstract, $params) allows param overrides
  • makeWith() is the same as make()
  • offsetGet(), __get() are the same as single-arg make()
  • factory($abstract) returns a Closure that calls make()
  • get($abstract) is a PSR-11 compliant (exceptions) make()
  • Events - can be global or specific to an abstract
    • Global callbacks in a group are fired first
    • $callback($instance, $container)
    • Return value is unused
    • resolving()
    • afterResolving() - fired immediately after resolving()

get ready for some Reflection

Reflection

Method bindings

  • bindMethod($method, $callback)
    • $method can be Class@method or array-style
  • hasMethodBinding()
  • callMethodBinding($method, $instance)
    • $instance is first param passed to the bound method
    • Container is second

injecting callables with call() and BoundMethod::call()

You can also curry closures with wrap($closure, $params = [])

Static Methods

  • getInstance()
  • setInstance()

Thanks! QUestions?

Slides: ian.im/LC0319 (and I'm @iansltx)