Dependency injection is a software design pattern that supports inversion of control and seperation of concerns. See Wikipedia Dependency injection for an introduction.
One way to do this is to inject dependencies into the constructor of a Javascript (Constructor injection). Another way is to inject the dependencies into the properties of the Javascript object.( lets call it property injection).

Both approaches need an object called Injector that allows to register dependencies that others depend on.

//create the injector

var injector=new prefabware.injector.Injector();

An example for a dependency may be some kind of service

var logger={      
        log:function(text){console.log(text);}
    };

and an object that depends on a service may be a client

var client={
        //the injector will find this property and set it to the according service

        logger:null,  
        //using the looger..

        log:function(text){this.logger.log(text);}
        };

Constructor injection parses the signature of the constructor function for the argument names and uses call the constructor using the according dependencies as parameters. This doenst work, when the code is compressed or obfuscated, because the names of the arguments are changed. There is a workaround for that, but it requires to repeat the argument names as a string list. A bigger problem I had when using constructor injection, is that you need all dependencies ('services') instantiated before creating an object, a 'client'. In a complex application, the dependencies form a tree and determining the order of instantiation can get complicated.

So for me it turned out to be much easier to use property injection, where you create the instances in one step and inject dependencies later. The trick is to set the properties to an initial value, that enables the injector to inject the desired dependency.
register the service using an id :

injector.register({id:'prefabware.logger'},logger);

and mark the property, with the same id, so the injector can inject the dependency

..
logger:{inject:'prefabware.logger'} 
..

finally let the injector inject the dependencies

injector.injectInto(client);

You can find a working example in jsbin .
The Injector uses dojo and is part of appdriver appdriver

Comments

comments powered by Disqus