On what level(s) should I worry about dependency injection in my node js application?

I'm building a Node JS module which has dependencies on other modules, I'm trying to ascertain the most appropriate approach to take in terms dependency injection, and on which application layer I should implement it to ensure objects are separated from each other.

I have two conflicting trains of thought on this and want to get some outside opinion to help steer course.

A) On one hand I could tackle injection at a application 'boostrap' level. My main server entry point would include and setup all required modules, and inject dependencies. This could look like:

server.js file (main entry point):

server = restify.createServer().use(restify.queryParser());

mongoose.connect(database_connection_string);

myModule = new AwesomeModule();

myModule.attach(restify, mongoose);    

In this example, my main application bootstrap file is instantiating all needed objects and injecting them into my module. This maintains separation of module dependencies at an application level.

B) Approach B would be to allow my Module to encapsulate the dependencies it needs to operate. This approach is taken by many modules in the Node JS community, but does it conceptually break the dependency injection pattern?

An injection is the passing of a dependency (a service) to a dependent object (a client). The >service is made part of the client's state. Passing the service to the client, rather than >allowing a client to build or find the service, is the fundamental requirement of the pattern. Dependency Injection on Wikipedia

An example of this for my application would look roughly like:

server.js (main entry point):

myModule = new AwesomeModule(database_connection_options, server_options);

myModule.run();   

index.js (inside my module):

var MyModule = function(database_connection_options, server_options) {

     // Anther option is to load the config object in here creating even more hardcoded           dependencies        

     this.prototype.server = restify.createServer(server_options).use(restify.queryParser());

     this.prototype.database = mongoose.connect(database_connection_options);

}

In this example, my module contains it's dependencies (in it's own node_modules directory) and sets up the services it needs, however objects are now instantiating each other which breaks the model of dependency injection.

Characteristics of these approaches:

A)

  • Application is more modular and easier to maintain.
  • Developers can create one server, and attach multiple modules like mine to it.
  • Developers can create one server and attach multiple instances of my module with different database configurations to it.
  • My module may fail if the developer uses a different dependency version in their bootstrapping files.
  • More bootstrapping is required for each application, but may be more flexible.

B)

  • My module contains everything it needs to operate (including the correct versions of dependencies).
  • This seems to be the approach encourages by the way NPM works.
  • Developers cannot attach multiple instances of my module, or other modules, to the server as my module is setting the server up internally.

Thanks