January 27, 2008

Another PHP dependency injector.

Filed under: PHP, Downloads — Marcus @ 11:46 pm

After working with Spring and Grails recently, I became very comfortable with their method of dependency injection. Based on my experiences, I went and wrote a simple injector that will automatically wire dependencies by name. At first it might seem to have quite an overhead, but in profiling with 40 or so objects being injected in a single request, its footprint was quite light.

Download the injector

Examples in the testing as a basic unit test, or click on for more

Usage:

Define your service classes in a folder in your application. Create a new instance of NovemberInjector passing that folder as the constructor. Call loadServices with an optional config parameter which will load and bind those service classes. Call inject to inject arbitrary objects with those services.

Assuming the class

Code (php)
  1.  
  2. class TestObject
  3. {
  4.     public $sampleService;
  5. }

and service object

Code (php)
  1.  
  2. class SampleService
  3. {
  4. }

and there is a folder ‘/services’ containing a file called “SampleService.php” which declares a class SampleService, then the following code will automatically bind this dependency (note the requirement for the ‘public’ service declaration).

Code (php)
  1.  
  2. $injector = new NovemberInjector(‘/services’);
  3.  
  4. $injector->loadServices();
  5.  
  6. $myObject = new TestObject();
  7.  
  8. $injector->inject($myObject);

You can override the implementation of a particular named service by passing a configuration that declares the ‘replace’ parameter. Also, it’s possible to pass in other parameters that will be passed to the service if it declares the ‘configure’ method.

Take the following service object

Code (php)
  1.  
  2. class AnotherService
  3.  
  4. {
  5.  
  6.     public $testValue;    public function configure($config)
  7.  
  8.     {
  9.  
  10.         if (isset($config[‘config_property’])) {
  11.  
  12.             $this->testValue = $config[‘config_property’];
  13.  
  14.         }
  15.  
  16.     }
  17.  
  18. }

The following will configure this object and register it in the injector in place of the ‘SampleService’ previously declared.

Code (php)
  1.         $injector = new NovemberInjector(‘/services’)$servicesConfig = array (
  2.  
  3.         ‘AnotherService’ =>
  4.  
  5.         array (
  6.  
  7.           ‘replace’ => ‘SampleService’,
  8.  
  9.           ‘config_property’ => ‘Value’,
  10.  
  11.         ),
  12.  
  13.  );
  14.  
  15. $injector->loadServices($servicesConfig);
  16.  
  17. $myObject = new TestObject();
  18.  
  19.  $injector->inject($myObject);

Finally, it’s possible to register objects with the injector that will be dynamically available in any injected object, regardless of whether they declare it as a dependency. For example, the following will register a logging object that will automatically be available for use in TestObject, despite it not having been declared there

Code (php)
  1. $this->injector->addAutoProperty(‘log’, new Logger());
  2.  
  3. $myObject = new TestObject();
  4.  
  5. $injector->inject($myObject);
  6.  
  7. $myObject->log->debug("See?");

There’s some basic examples in the form of a unit test in the testing directory that shows the basics of usage.

Download the injector

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

.

Powered by WordPress