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.
1 Answer 1
I'm not quite sure what your code is doing, but I'm pretty sure it's not something I'd recognise as dependency injection. Specifically, it seems as though your client object is responsible for finding its dependencies from a central repository during construction (albeit using a dependency name that's phased as a constructor parameter), which strikes me as closer to the Service Locator pattern than Dependency Injection.
-
Hold on, the constructor isn't actually the client though. I just read something in the Wikipedia article which which says the constructor can be the injector: The injector may be referred to by other names such as: assembler, provider, container, factory, builder, spring, construction code, or main.J.Todd– J.Todd09/27/2015 16:40:07Commented Sep 27, 2015 at 16:40
-
I don't think that means the usual object-oriented concept of a constructor, but rather a dedicated section of code with the responsibility of creating all the long-lived objects in the system.Jules– Jules09/27/2015 17:28:18Commented Sep 27, 2015 at 17:28
Explore related questions
See similar questions with these tags.
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.