Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 570
user502014 Avatar asked Jun 24 '26 00:06

user502014


2 Answers

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();
}
like image 173
Chris Tavares Avatar answered Jun 25 '26 13:06

Chris Tavares


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();
};
like image 27
Wouter J Avatar answered Jun 25 '26 13:06

Wouter J