occasionally useful ruby, ubuntu, etc

6Dec/090

LockNLoad is…locked and loaded?

I've just completed and pushed the initial version of LockNLoad, a Spring-like Inversion of Control container for Javascript, which follows the dependency inversion principle (I think I'm getting all these terms right...). Given the proper configuration, you can simply say LNL.$("my_id") and get a prototype or singleton object or function. Read on for more information.

The background story is I wanted to make a game library in Javascript for an experiment with Titanium, and I found that one of my components was Titanium-specific (the one for playing sound). My game library was generic enough to be used in any browser except for the sound feature, and so I found myself passing around a reference to the sound function I needed to instantiate based on the platform. But that's dumb! I should just be able to say container.get("sound_type") and instantiate that, and let the container figure out what platform I was on and what sound object I needed. So I made LockNLoad, which is that container.

Carrying on with the previous story, my classes might look like this:


function RegularSound(){
  this.playSound = function(snd){
    $(document).append("");
  }
}

function TitaniumSound(){
  this.playSound = function(snd){
    Titanium.Media.Sound.play("app://" + snd);
  }
}

Normally, your options are to pass around a reference to the function so you can instantiate it, put "if titanium instantiate TitaniumSound else instantiate RegularSound" everywhere in your code, or create a function that abstracts away the method call in the previous suggestion.

Following the dependency inversion principle, you ARE abstracting away the function that creates the Sound object.

Continuing: configuration:


var config = {
    "sound": {
        "class": RegularSound
    }
};
if(Titanium){
  config.sound.class = TitaniumSound;
}
LNL.loadConfig(config);

Finally, the calling code would look like this:


var mySound = LNL.$("sound");
mySound.playSound("monkey_laugh.mp3");

It can do other stuff too, like singleton, setting properties on the returned object, and returning raw functions. The example given is the simplest possible functionality it can provide.

Interested? It's up on github, with a complete README with all the details. Link: http://github.com/nanodeath/LockNLoad

It doesn't do dependency injection yet, and might never if no one cares :) but it would be nice if it could store arbitrary objects, not just classes and functions, so I'll be adding that soon.

Comments (0) Trackbacks (1)

Leave a comment