I'm re-evaluating my thoughts on constructor based dependencies vs setter dependencies in JavaScript. I'm trying to see if the same reasons we avoid setter injection in static language like C# and Java still apply in JavaScript.
In other words, why is this:
var a = new A();
var b = new B();
var c = new C(a, b);
better than this:
var a = new A();
var b = new B();
var c = new C();
c.a = a;
c.b = b;
What are the reasons that you would choose constructor parameters vs setters, and why?
What other options are there for runtime composition of the c
object, so that it can correctly make use of a
and b
? When would you choose those options?
@mbriggs - good info. i especially like the bit about destructuring. that could still be done with a setter method (as opposed to just assigning an attribute), but I agree that the encapsulation feels better to me when it's in the constructor.
fwiw, though, I see IoC containers in JS as an anti-pattern. It's as if we've become so used to the necessity of them in languages like C# and Java that we forgot what problems they introduced when looking at what problems they solved. I've never found a legitimate need for them in JS. The times when I thought that it would be necessary or helpful were the times that I was ignoring the pain of the design I was implementing: object graph too deep, tight coupling between processes that should be separated, etc. Typically flattening the object graph by recognizing additional boundaries within our objects will make the need for an IoC container go away, IME.
@jbogard is right about having more options available in JavaScript and needing to explore and understand those options, when they're useful, when they're detrimental, etc (via our twitter conversation). and even though i react against his suggestion here, i end up doing that on a regular basis - mocking
$.ajax
calls, for example.I still don't like setter injection, especially when it takes the form of
foo.bar = baz
. If I were going to do setter injection, I would create a setter method. This at least gives a legitimate API for the purpose of setting the dependency, which has more value in declaring the intention of the code than simple attribute assignment.... so much to think about. so little time :P