I'm trying, as a test, to create Dependency Injection from scratch in JavaScript. Consider the following code structure, which outputs an Alert:
- Does it satisfy the terms of the Dependency Inversion Principle?
- Is it technically Dependency Injection?
- and if not, what structural changes are necessary?
-
function App(name, services, clients) {
var that = this;
this.name = name;
this.services = services || {};
this.clients = clients || {};
this.Service = function (func) {
func();
}
this.Client = function () {
this.dependencies = {};
for (var i = 0; i < arguments.length; i++) {
if (that.services[arguments[i]]) {
this.dependencies[arguments[i]] = that.services[arguments[i]];
}
}
}
}
var fooBar = new App('fooBar');
fooBar.services.alert = new fooBar.Service(function() {
alert('Yep!');
});
fooBar.clients.alerter = new fooBar.Client('alert');
fooBar.clients.alerter.alert();
One of the structural aspects of this structure that I'm not sure about is the fact that in the above code, the client
's constructor knows about the code to inject dependencies.
Wikipedia says:
Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern. The client is not allowed to call the injector code.
However, an answer on this site explaining the naming of dependency injection mentions the constructor can inject the dependency:
Let's say you have some sort of "repository" class, and that repository is responsible for handing data to you from a data source.
The repository could establish a connection to the data source by itself. But what if it allowed you to pass in a connection to the data source through the repository's constructor?
Note, the above is shortened (working) code, I omitted code involved in defining services in order to make the code sample simpler (also omitted strict error handling in case of a missing dependency) - the overall structure should be apparently correct or incorrect - that's the focus of the question, not the specific implementation.
Client
handles the dependency gathering, but I haven't been able to figure out how to make a separate component inject the dependencies in a way that makes any sense.