Skip to content

AmPHP Injector

Garrett W edited this page Aug 30, 2021 · 1 revision

amphp/injector may not support PSR-11 natively (I need to check this) but there's still plenty to learn here.

Features in brief

  • Auto-wiring
  • Handles non-concrete type hints using the variable's name as well as either a class name or a literal -- at configuration-time or instantiation-time
  • Can share an instance across the object tree based on the constructor parameter name
  • Delegate object creation to a user function (this is also used as a flexible solution to implement post-instantiation method calls)
  • Setter injection / post-instantiation mutations
  • Can work its auto-wiring magic on any PHP callable as well as instantiating objects referred to by a non-static class method reference

Principles

Resolves dependencies in the following order:

  1. If a shared instance exists for the class in question, the shared instance will always be returned
  2. If a delegate callable is assigned for a class, its return result will always be used
  3. If a call-time definition is passed to Amp\Injector\Injector::make, that definition will be used
  4. If a pre-defined definition exists, it will be used
  5. If a dependency is type-hinted, the Injector will recursively instantiate it subject to any implementations or definitions
  6. If no type-hint exists and the parameter has a default value, the default value is injected
  7. If a global parameter value is defined that value is used
  8. Throw an exception because you did something stupid

Configuration details

My opinions

  • I don't like the method of configuring the container by calling void methods. This means the object is more mutable than I would want.
  • Similarly, different methods are called in order to configure the same class name in different ways (see share, define, alias). Truthfully the container object's primary responsibility is not to construct a configuration.
  • I don't like the way raw parameters are supplied, by prefixing the param name with a colon. This feels hacky and is definitely not self-documenting. Might be better to just detect if the param value is a valid class or not.
  • When share()ing preconstructed instances, you don't get the opportunity to specify an exact typehint that would be replaced with this object. This is a potential drawback, especially when working with inheritance trees if you need to supply different sub-class objects to different parts of the tree while all instances typehint the same root class.
  • I greatly prefer this library's delegation functionality over Dice's, as it is just more flexible.

Clone this wiki locally