0

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.

12
  • Note, I'm not asking about improvement (which would be off-topic) but just about fundamental issues/changes necessary in the structure or syntax.
    – J.Todd
    Commented Sep 26, 2015 at 11:19
  • is it even possible to do DI without type safety?
    – Ewan
    Commented Sep 26, 2015 at 12:22
  • 1
    Possible? or wise? Commented Sep 26, 2015 at 17:19
  • @Ewan this is just minimal code, to get the structure across. I will add features but first I'm checking whether or not the structure is in fact Dependency Injection. I think there's a structure issue since the 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.
    – J.Todd
    Commented Sep 26, 2015 at 19:18
  • 1
    Jules is referring to a DI container. But you don't need a DI container to do DI. DI containers just allow you to wire up all of the object dependencies automagically. The constructor is not the injector; the object or method that is calling the constructor is the injector. Commented Sep 27, 2015 at 19:59

1 Answer 1

2

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.

2
  • 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
    Commented 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
    Commented Sep 27, 2015 at 17:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.