IoC for Javascript & Node.js

Lazy loading

Lazy loading is a design pattern commonly used in programming to defer initialization of an object until the point at which it is needed.

Sometimes an object should only be loaded in certain contexts. Lazy loading avoids unnecessary load objects, the object is loaded on demand.

Lazy loading of objects

Each services constructors are singletons, so:

// defines the serviceId in `noder.$di`
// without calling the factory function (service constructor)
noder.$singleton('serviceId', function() {

  var myService;

  // function body that constructs `myService` object

  return myService;
});

See services for more details concerning the services in Noder.io.

Lazy loading of modules in Node.js / CommonJS

The method noder.$require provides a lazy require().

// define the property without loading the mongoose module
noder.$require('mongoose');

// false
console.log(noder.$require.isLoaded('mongoose'));

// lazy loading
var mongoose = noder.mongoose;

// true
console.log(noder.$require.isLoaded('mongoose'));

// true
console.log(noder.mongoose === require('mongoose'));

Register a module

Register marked property that will contain the marked when it is called:

   // Note: `marked` module is not loaded
   noder.$require('marked');

   // Now load (on demand) the `marked` module in the `markdown` property
   console.log(noder.marked('I am using __markdown__.'));

   // true
   console.log(require('marked') === noder.marked);

Register with an alias:

   noder.$require('markdown', 'marked');

   console.log(noder.markdown('I am using __markdown__.'));

  // true
   console.log(require('marked') === noder.markdown);

Register with a custom loader:

noder.$require('marked', function() {

  var marked = require('marked');

  marked.setOptions({
    gfm: true // Github Flavored Markdown
  });

  return marked;
});

console.log(noder.marked('I am using __markdown__.'));

Example

// alias
noder.$require('promise', 'bluebird');

// factory: promisify the `fs` module
noder.$require('fs', function() {
  return noder.promise.promisifyAll(require('fs'));
});

noder.$require('readDir', './lib/read-dir');

noder.readDir('./mydir').then(function(file){
  console.log(file.join('\n'));
});

File ./lib/read-dir.js:

var noder = require('noder.io');
var path  = require('path');

// Reading directory and sub-directory contents recursively
module.exports = function readDir(dirName) {

  var fs = noder.fs;

  return fs.readdirAsync(dirName)
    .map(function (fileName) {

      var filePath = path.join(dirName, fileName);

      return fs.statAsync(filePath).then(function(stat) {
        return stat.isDirectory() ? noder.readDir(filePath) : filePath;
      });
    })
    .reduce(function (a, b) {
      return a.concat(b);
    }, []);
};