Reputation: 2331
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
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
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
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
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