Wednesday, July 15, 2015

Reminder of Wirebox Dependency Injection Lifecycle

I remember reading it in the Wirebox Ref Card, but I actually ran into an issue with Wirebox dependency injection and a race condition today.  I wanted to blog about it just in case you started with Wirebox without reading the documentation end-to-end ;)

When you are using Wirebox mixin injection to autowire properties, dependencies are not injected until after your pseudo-constructor is called.  Here is an example that will fail:

 component accessors="true" {  
   property name="myDAO" inject="";  
   public function init() {  
     getMyDAO().myMethod();  
   }  
 }  

This will cause an error since myDAO has not been injected into the component before init() is called.  The solution is pretty simple:

 component accessors="true" {  
   property name="myDAO" inject="";  
   public function init () {  
   }  
   public function postInit() onDiComplete {  
    getMyDAO().myMethod();   
   }  
 }

Adding the onDiComplete annotation to the postInit() method tells Wirebox to run the method after it has instantiated the object and injected any dependencies.  I did notice that the method must be public which is unfortunate, but it makes sense.  This simple example is pretty useless, but in my case I needed to store a query into a singleton on instantiation so this was just the ticket.

2 comments:

  1. I prefer the more portable constructor injection syntax for this reason (as well as it makes the object truly agnostic of the DI engine):

    /**
    * @myDao.inject myDao
    *
    */
    public any function init( required any myDao ) {
    // stuff...
    }

    ReplyDelete
  2. Yes Dom, I believe that constructor injection is the only way to avoid having to use onDIComplete() or the onDIComplete method annotation. For both mixin injection and setter methods Wirebox waits to perform DI until after init() is called to prevent circular references.

    ReplyDelete