user502014
user502014

Reputation: 2331

Dependency injection in javascript

I have been playing around with dependency injection with javscript but have some questions that I need help with

A simple example is a dialog module I have, used in multiple places on the page it alerts a user with a custom message when a user interacts with a component on the page

function Dialog () {

}

Dialog.prototype.show = function () {

}

and this may be used in a component, say a search control which validates a user search and if its empty it fires an error dialog. With dependency injection I'm assuming I would write:

function searchComponent (dialog) {
   this.dialog = dialog
}

searchComponent.prototype.validateSearch = function () {
    // validate search if invalid create error
    this.dialog.show();
}

var searchDialog = new Dialog();
var search = new searchComponent(searchDialog);

However a user may never need the search error dialog, yet I am creating an instance of it just so that I can then pass the dependency through, what if I have 100 individual instances of a dialog on the page do I construct these 100 times, this is unnecessary and expensive in performance.

what I would rather do is lazy load the construction of a dialog to a time when it is needed

searchComponent.prototype.validateSearch = function () {
  //validate search if invalid create error
  var dialog = new Dialog();
  dialog.show();
}

now I know that this creates disadvantages and one of these is the affects it has on unit testing, what I am keen to understand is whether I have missed something or an alternative method?

Thanks in advance

Upvotes: 2

Views: 1937

Answers (4)

amwmedia
amwmedia

Reputation: 31

I recently wrote a dependency injection library called infect.js. Check it out, might just be what you're looking for. https://github.com/amwmedia/infect.js

Upvotes: 0

Mike
Mike

Reputation: 263

Inspired by the previous examples, I've created a simple jsFiddle that utilizes a small library called Syringe.js in order to show how dependencies can be injected by pre-binding the SearchComponent constructor.

When a SearchComponent object is created, the validator dependency (a separate component, here taking the place of an actual dialog) is automatically provisioned. This dependency is subsequently used by the validateSearch method.

The advantage of doing it this way is that you don't have to have any dependencies in your hand when you create each SearchComponent object instance.

In addition, the validator dependency can be modified after theSearchComponent objects are created, and the behavior of the dependent control(s) can be updated accordingly.

Upvotes: 1

Wouter J
Wouter J

Reputation: 41934

To extend @ChrisTavares' great solution, you can use something like this to make dependency injection inside the Dialog possible as well:

var foo = function () { return new Foo() }; // just an example
var search = new SearchComponent(function() {
    return new Dialog(foo());
});

Inside your SearchComponent:

function SearchComponent(Dialog) {
    this.Dialog = Dialog;
}

SearchComponent.prototype.validateSearch = function () {
    var dialog = new this.Dialog();
    dialog.show();
};

Upvotes: 1

Chris Tavares
Chris Tavares

Reputation: 30411

JavaScript functions are first class objects. Instead of passing in a constructed dialog, pass in the dialog constructor function:

var search = new SearchComponent(Dialog);

Then new it up when you need it:

function SearchComponent(Dialog) {
  this.Dialog = Dialog;
}

SearchComponent.prototype.validateSearch = function() {
  var dialog = new this.Dialog();
  dialog.show();
}

Upvotes: 7

Related Questions