divsmith / airlock
IoC for non interface conforming dependencies.
Requires (Dev)
- mockery/mockery: 0.9.*
- phpunit/phpunit: 3.7.*
Replaces
- divsmith/decouplr: 1.0.1
This package is not auto-updated.
Last update: 2024-11-05 04:16:51 UTC
README
Airlock is a simple abstract adapter class to provide decoupling to dependencies that don't specify their own interfaces.
Installation
Install Airlock by adding the following to your composer.json file
{ "require": { "divsmith/airlock": "1.*" } }
Usage
-
Create an interface specifying the methods of the concrete dependency you are going to depend on.
interface ExampleInterface { public function method1($args); public function method2($args); etc... }
-
Create an adapter class that extends Airlock and implements the interface.
class ExampleInterfaceAdapter extends \Airlock\Airlock implements ExampleInterface { public function method1($args) { return $this->delegate(__FUNCTION__, func_get_args()); } public function method2($args) { return $this->delegate(__FUNCTION__, func_get_args()); } }
Each method needs to contain
return $this->delegate(__FUNCTION__, func_get_args());
or it will not behave as expected.
-
Inject the concrete dependency via the adapter constructor. This can either be done by using the predefined Airlock constructor
$adapter = new ExampleInterfaceAdapter(new ConcreteDependency());
or typehinted and injected via an IoC container
class ExampleInterfaceAdapter extends\Airlock\Airlock implements ExampleInterface { public function __construct(\Namespace\ConcreteDependency $dependency) { $this->locker = $dependency; } ... }
-
Enjoy! You can now typehint the interface and inject the adapter instead of the concrete dependency (assuming appropriate IoC bindings). Use the adapter exactly as you would the concrete dependency and sleep better at night knowing that your code is decoupled from it.
Other Usage
You can use Airlock with empty interfaces that simply provide latches for your IoC container to resolve. Just inject your concrete dependency into your adapter and let Airlock do the rest. Not as architecturally sound as a well defined interface, but it gets you the benefits of not being tied to the concrete dependency while not requiring you to define each method in the adapter.
interface ExampleInterface {}; class ExampleAdapter extends \Airlock\Airlock implements ExampleInterface{ public function __construct(\Namespace\ConcreteDependency $dependency) { $this->locker = $dependency; } }