6

Following this question

https://stackoverflow.com/a/2465052/41948

So Python doesn't need IoC/DI because it's dynamic scripting language already.

Javascript is also a dynamic scripting langauge, why does angularjs need DI then?

Is it because JSON <-> DOM is static? Could someone give me a minimal example?

Community
  • 1
  • 1
est
  • 11,429
  • 14
  • 70
  • 118
  • 1
    To my knowledge (some talk on youtube by misko and the other guys) DI in angular was a deliberate decission not a need. Primarily to make testing easier/possible. – Yoshi Sep 25 '13 at 08:53
  • 1
    I wouldn't say angular needs DI. It's more of an additional tool to structure your application. – David Sep 25 '13 at 08:53
  • In facgt is very smart and usefule to have a DI. Because AngularJS can mange the two data-binding the runtime of factories, controllers, runtime with it via _invokeQueue. Without it, and just with dynamic language how to structure correctly your app ? – Thomas Pons Sep 25 '13 at 09:10

4 Answers4

11

Dependency Injection (DI) in Angular wasn't a necessary decision. Most other JavaScript frameworks don't have it built in. (Although look at Marionette, a framework built on top of Backbone.js... it includes an optional DI layer). Angular.js comes with a set of architectural opinions that help you separate your code. It was built in as a design decision, not a necessity.

The biggest reason it is necessary for YOU to use DI in Angular is because that is the way Angular works. The angular team could have decided to use an Asynchronous Module Definition (AMD) library like Require.js. Instead they chose a DI pattern and baked it in for convenience.

The link you posted suggests that DI might be an anti-pattern in dynamic languages. I disagree with that. I'd just say that DI is less necessary in dynamic languages. In the case of Angular, however, it works well. They allow you to compose your system of parts and inject only what you need, when you need it. When you look at the way other frameworks do it, they (often) just namespace their Model/View/Controller/Template/Router parts in the global space (Like App.Models.Person in Backbone.js).

I find DI in Angular to be like "When in Rome, do as the Romans do". Embrace the architectural decision. It feels good.

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
4

The best use case for the DI is when you are building an extremely large application with testing. In that case you will likely be very modular and have dozens of components that can come together to form a page. The classic issue with JavaScript is timing and when to include the scripts, check to see if they are already loaded, etc. The DI eliminates that. As long as you get the script included - however you like, whether it's a direct include or an asynchronous module load or a bundle or a combination - AngularJS will handle the rest. You don't have to worry about order because AngularJS will walk the dependency tree for you and assemble the components in the correct order, and you don't have to worry about lifetime management because AngularJS will maintain the appropriate instances for you.

Jeremy Likness
  • 7,531
  • 1
  • 23
  • 25
  • +1 Another great point about DI. You can inject test doubles without DI, but DI makes it a whole heck of a lot easier... – Brian Genisio Sep 26 '13 at 09:47
3

Well, first thing, IoC and DI are two different things (DI is a type of IoC, very popular in static languages). DI isn't very popular in python, but other IoC paradigms are popular, such as Service Locator. Django serve partly as a service locator (for services such as settings, caching, storage, etc..).

You need to remember that Javascript doesn't have any import capabilities (html does, but javascript itself doesn't, though it is planned for ES6), and unlike python, if you want to build modular applications with intricate inner dependencies, you don't have any way in code to describe your dependencies (or get them).
If you don't use somekind of dependency management framework (such as require.js), you are forced to use the global object (or an object inside the global object) as a service locator (which is what other frameworks and plugins do).

The choice of DI instead of service locator in angular is a design decision, which I'm guessing was decided because of two main reasons - the first is unit testing, DI is very amendable to unit testing. The second is probably future proofing for things like ES6 modules.

Alon Bar David
  • 1,757
  • 14
  • 15
2

I know this is an old question but since there is still lot of people finding this confusing I guess that it is worth to mention that everything that can be done with the DI approach can be done with plain CommonJS. Or at least the following:

  • Inject test doubles during testing (overloading the require function like proxyquire or karma-commonjs-plus
  • Replace services in runtime (using browserify exports and require options)

I haven't yet found an instance of something provided by Dependency Injection approach that cannot be done Simpler with just plain commonJS.

For sure if you're not using commonJS, AMD or other modular approach you only have the angular one, in that case you should evaluate at least start using one, it will make your life insanely easy without requiring DI.

That said, DI is a very powerful concept, one that cannot be underestimated, only not that needed in Javascript as in other languages.

roy riojas
  • 2,406
  • 1
  • 28
  • 30
  • 1
    I have found that for all practical purposes Angular JS Dependency Injection in any large complex non trivial system ends up being an anti-pattern. Take the simple example of trying to debug the linkage of the injected dependency. This is practically impossible. The side effect of Dependency Injection is that the logic execution paths and invocation paths become non deterministic - which translates into "A plethora of bugs". Anything done via dependency injection can be done simpler and without it. Famous Quote: "Any intelligent fool can make things bigger, more complex, etc..." – tcwicks Nov 26 '16 at 10:30