16

Are there any inversion of control frameworks for javascript?

The closest answer available on stackoverflow that I could find is here: What is the right way to wire together 2 javascript objects? . It looks like a great start, but I thought I'd be able to find something with a longer development history.

I've only used Castle Windsor myself, and I am really missing it in web-client land.

Community
  • 1
  • 1
Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130
  • You can just have the functions renamed in a different file, why do you need a framework? – James Black Sep 15 '09 at 04:27
  • There's a lot more to it than that. In JasFac (see my answer) I haven't even begun to scratch the surface of what can/should be done. It's a big topic. JavaScript usually just tends to use Service Locator style patterns, totally bypassing IoC – Luke Schafer Sep 15 '09 at 04:40
  • A couple responses are from people who like IoC but did not actually end up using their solution. I'd be curious how the kept their objects decoupled then. Using a service locator? – Frank Schwieterman Sep 15 '09 at 16:55

12 Answers12

4

I started writing one that I never got around to finishing. Not sure if I ever will as the overhead probably isn't worth it. if you're interested, it's at: http://code.google.com/p/jasproject/wiki/JasFac (that's the IoC portion, the full suite is at http://code.google.com/p/jasproject/)

The mocking library is fairly complete (no expectations though, at the moment i just use assertions on the mocks/stubs) but the unit testing framework is lacking. The IoC portion is pretty complete but might have a few bugs (don't think so though)

Feel free to use it and/or contribute, I can help where you need.

EDIT: More usage can be seen in the unit tests for jasfac: https://jasproject.googlecode.com/svn/trunk/Jas.Tests/JasFacTests.js

Luke Schafer
  • 9,209
  • 2
  • 28
  • 29
  • 1
    Can you elaborate on why you did not need it? – Frank Schwieterman Sep 15 '09 at 16:48
  • Well, as I said in the other comment, most people use service locators for this sort of need in JS. Additionally, The size of your JS really does matter, so unless you're making a _really_ thick client, you want to minimise as much code-size and computation as possible. See http://video.yahoo.com/watch/1041101/3881103 – Luke Schafer Sep 16 '09 at 06:47
4

I was looking for one last year and ran across squirrel-ioc. There was something I didn't like about it - I think it only supported singleton style instances.

Squirrel is an IoC container implemented in Javascript to promote the better use of architecture and patterns in browser-based Javascript applications

I started writing my own and got pretty far (constructor and setter injection, values and reference relationships, singleton support, JsUnit tests) but never really needed it in my application. I may have to check out Luke's project. For reference, here is an example of the configuration format I ended up with.

var iocConfig = {
  "a" : { Type : A },
  "b1" : { Type : B, Props : [{Name : 'Letter', Ref : "a"}]  },
  "b2" : { Type : B, Props : [{Name : 'Letter', Val : "a"}]  },
  "c2" : { Type : C, Args : [{Ref : "a"}, {Val : "a"}]  },
  "d" : { Type : D, Props : [{Name : 'Letter', Ref : "a"}]  },
  "date" : { Type : Date, Props : [{Name : 'FullYear', Val : 2008}, {Name : 'Month', Val : 0}, {Name : 'Date', Val : 1}]  },
  "array3" : { Type : Array, Args : [{Val : 3}]  },
  "number1" : { Type : Number, Args : [{Val : 1}]  },
  "string1" : { Type : String, Args : [{Val : "1"}]  },
  "s-true" : { Type : S, Singleton : true},
  "s-false" : { Type : S, Singleton : false}
};
Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155
  • Yeah I wasn't a fan of squirrel either, hence writing my own. I had the same thing - started it but didn't have a real need for it so never finished. Take a look at the source of mine, especially the unit tests, there's a lot more you can do with it than the site ways. – Luke Schafer Sep 15 '09 at 05:59
  • 4
    Can you elaborate on why you did not need it? – Frank Schwieterman Sep 15 '09 at 16:50
3

I put together a simple lightweight ioc container, called it JsfIoc.

http://github.com/fschwiet/JsfIoc

Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130
1

Check out Inverted http://philmander.github.com/inverted/, a feature packed Javascript IOC container I have created. It runs on top of AMD in the browser and also works with Node.

Used in conjunction with AMD, Inverted uses a separate configuration file to express how classes are instantiated and how they interact. Once these defaults and relationships have been defined, an application context can be created, and instances of the classes can be used.

http://dailyjs.com/2013/01/04/controldeck-xlsx-inverted/

Phil Mander
  • 1,819
  • 15
  • 20
1

I have create and IoC container for JavaScript apps please check it out at http://blog.wolksoftware.com/introducing-inversifyjs

Remo H. Jansen
  • 23,172
  • 11
  • 70
  • 93
0

In dynamically typed languages like JavaScript and Ruby, DI isn't really that beneficial.

The main benefit of DI in statically typed languages like Java is in testing - to replace the real implementation of some class with a mock. That's because in Java classes are immutable and you can't just that easily replace them with mocks - you need a whole DI system to accomplish that.

But in JavaScript you can easily replace existing classes/methods with mocked ones. So DI is not really needed to achieve testability.

Of course there are other scenarios where DI might be useful, but you haven't really pointed out what you want to use the DI for, so I covered the most obvious case.

Rene Saarsoo
  • 13,580
  • 8
  • 57
  • 85
  • 7
    I think DI is different from IoC. Yes DI is easy in Javascript as you can write where ever you want, I am using DI currently for unit testing. Although DI is much easier in Javascript, I think IoC could still have advantages in documenting dependencies and in making test code cleaner. Right now when I test something I have to manually verify every dependency has been properly replaced. With IoC you can clearly see what dependencies exist and what they've been replaced with. – Frank Schwieterman Sep 18 '09 at 16:58
  • 2
    I'm just passing through so I don't have time to look up a reference, but DI is not just for testing (it's not even the main benefit). – Luke Schafer Sep 29 '09 at 05:49
  • I hear this opinion a lot. I don't agree. How do you dynamically rebind the functions on a service object that is private and created internally inside another function for testing? What you say is simply not true. The benefit of being dynamic is you can dynamically create mock objects which you can then use _with DI_; ie. you dont need mocks, not you don't need DI. down vote. – Doug Dec 08 '11 at 02:34
0

We built a simple JavaScript IoC container called hilary.js: https://github.com/Acatar/hilaryjs.

With hilary, you can register and resolve services and factories. It supports child containers too, if you need or want to scope your containers.

EDIT I added some examples using hilary, as well as an example of achieving Dependency Injection with require.js:

andes
  • 514
  • 3
  • 6
0

Try canDI. It's a simple dependency injection and object creation library. You can create singletons, instances and variables that are automatically registered at creation.

https://github.com/bflemi3/canDI

bflemi3
  • 6,698
  • 20
  • 88
  • 155
0

I use one, here's simple code from specs (it's CoffeeScript):

di.register 'a', -> 'component a'
di.get('a').should be: 'component a'

There are also callbacks, different scopes (application, instance, custom), ability to explicitly assign components.

DI: https://github.com/alexeypetrushin/rad_core/blob/master/assets/lib/dependency_injection.coffee

Spec: https://github.com/alexeypetrushin/rad_core/blob/master/assets/lib_spec/dependency_injection_spec.coffee

I use it to assemble Backbone.js application, there are lots of objects (App, Menu, Notice, ...) and it's make my life easier.

WARN: I use it internally with altered native objects, so there may be some errors :) Please let me know about them, I probably fix it in a day or two (by submitting via issues page https://github.com/alexeypetrushin/rad_core/issues ).

P.S. Don't like the IoC term it's too broad, DI is much more exact definition.

Alex Craft
  • 13,598
  • 11
  • 69
  • 133
0

You could look at this simple library: fcjs It's very small but can be powerful in decoupling your code. It's inspired by Swiz AS3 framework

Szymon Wygnański
  • 10,642
  • 6
  • 31
  • 44
0

Another (newer) option is requireJS (http://requirejs.org/).

Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130
  • requirejs is great but definitely on the management side of the DI and dependency management line. – M.Babcock Feb 10 '13 at 01:52
  • 1
    requirejs provides dependency management, but it doesn't provide inversion of control - it always returns what was created up front, no way to tell requirejs you want a new instance of something every time, you need to return a function from your module and new it up manually, so yeah, pedantic, but valid ;) – jamiebarrow Feb 12 '14 at 13:06
  • I created an example of achieving Dependency Injection with require.js, which is to say that, while I agree it was built with dependency management in mind, I think you can achieve a clean approach to injection through pattern implementation: http://acatar.github.io/hilary/patternInAmdWithoutHilary/ – andes Jul 16 '14 at 21:38
-1

Try Infusion. It is a pretty powerful IoC JS framework. It is used by couple of research centers in universities of Toronto and Berkeley Infusion

GitHub page of the project with more information could be found here Infusion GitHub pages

anvk
  • 1,183
  • 8
  • 10