Hacker News new | past | comments | ask | show | jobs | submit login

Agree 100%. Things like dependency injectors have no real place in JavaScript, where programmatic wiring and modules already solve the problem in an idiomatic way. Angulars modules factories services etc are absurd and attempt to reinvent what the language naturally provides.



>> where programmatic wiring and modules already solve the problem in an idiomatic way

Can't agree with that. Not sure what you mean by 'programmatic wiring' as it sounds vague, but certainly modules do not solve the same problem that DI solves.

Modules, (assuming you mean stuff you require() or equivalent), provide module-level dependencies but do not provide object instances. For example, if an instance of House requires a Door it is not enough to just require('Door'). You still have to do the equivalent of `new Door()` in your House module to get an instance. By doing so within the House module you just tightly coupled House to Door (your House now knows how to create Doors).

DI allows you to provide an object with object instances it depends on without tightly coupling said object to those dependencies (pass a Door instance into a House instance, advantage being you can pass in any type of Door and House doesn't need to care - thanks polymorphism)!

I'm not sure that's a great explanation, but it's worth trying every now and then right?

You seem to be making the argument that the language provides alternatives, and it's true that in dynamic languages you can eschew some of the benefits of DI by doing monkey patching instead (e.g. to mock out an object's 'tightly coupled' dependencies during testing), but to myself and many OOP proponents DI leads to cleaner design and simpler tests.


For example, if an instance of House requires a Door it is not enough to just require('Door'). You still have to do the equivalent of `new Door()` in your House module to get an instance. By doing so within the House module you just tightly coupled House to Door (your House now knows how to create Doors).

So what? What is so bad about House and Door being "tightly coupled"? Here's a House constructor that can take any kind of Door instance:

    function House(door){
        this.door = door;
    }
This is JavaScript, let's stop trying to make it into Java.


What you just wrote as a code example is Dependency Injection, it's just manual dependency injection as opposed to using an IOC container or any of the mechanisms Angular provides.

I am very much in favour of the approach you posted. That's exactly how I write my code (I don't currently use Angular), but yep ... that's DI. As James Shore said 'Dependency Injection is a 25-dollar term for a 5-cent concept'. [1].

What you show in that code example is what in my head I call "poor man's DI" or ... "passing stuff in" but it's actually my favourite kind as it demonstrates the fundamental idea and is easy to explain to people - as soon as you start talking about IOC and service providers things start to get murkier. I think that's definitely where Angular is losing some people. You can get a long way with the basic "poor man's" approach.

[1] http://www.jamesshore.com/Blog/Dependency-Injection-Demystif...


>When I realized it was "passing stuff in" I wanted to shout, I have done that for years!

Well, it's the "automatic" part that is important, not just the DI.


So the setter gets called automatically, but now you have to store the object names as strings or in an XML file. How is that better?


Loose coopling?


Well, now the different classes inside your application are more loosely coupled, but your business logic is more tightly coupled to a DI framework.


I remember the first time I heard the term Dependency Injection. I sounded really advanced and I felt like a fool not knowing about. Like have been living under a rock for last years.

When I realized it was "passing stuff in" I wanted to shout, I have done that for years!


I felt the same way about DI until I watched this video: http://www.youtube.com/watch?v=_OGGsf1ZXMs


Fantastic video. I think it nails what DI is good for, and furthermore, what a DI framework is good for. Not only that, but it's a faaaaar more elegant solution than what's been in Angular so far.


  var prod_dependencies = {
    obj0: require('obj0'),
    obj1: require('obj1')
  };

  var test_dependencies = {
    obj0: require('mockobj0'),
    obj1: require('mockobj1')
  };

  var dependencies = test_dependencies;

  some_func(dependencies.obj0,dependencies.obj1);
Javascript does not need Java-style dependency injection. Javascript's configuration language JSON is valid Javascript.


You're slightly off on your definitions - what you show in that example is dependency injection.

You are injecting dependencies into `some_func` by passing them in. See my response to kyllo below.

I think what you are arguing against is using further patterns to facilitate dependency injection, e.g. IOC containers, or what Angular uses (service locators).



It isn't quite a solved problem in the regular ecosystem. Currently importation is rigid - you end up testing the functionality of what you are importing instead of purely the logic of your modules. The tests are polluted with logic that really tests both the details of how an api provided by another library functions under the hood.

DI is the solution to that. It has every place in a language like JS, and I am excited with having it available.


The topic of DI and/or IOC in dynamic languages is an interesting one.

I've seen a similar debate play out in the Python world and the debate seems to polarize into two camps:

"You have never built anything complex enough and therefore you don't understand the benefits of DI/IOC"

vs.

"You've come to a dynamic language from some verbose public static void main hell-hole and are suffering from some form of Stockholm Syndrome"




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: