Hacker News new | ask | show | jobs
by shadowmint 5096 days ago
You're almost always better off using an ABI and shared libraries than doing this.

That said, there are cases where it's useful; but remember: dependency injection is an anti-pattern that increases code complexity to facilitate run-time configuration and testing.

Without a helper IOC framework (that does the hard work of maintaining singleton instances and injecting the right ones in the right places at the right time) doing this is a lot of work in a large project.

...not saying it's a bad thing. It's totally a good thing, especially making your C code testable.

Just be aware that there are limitations and downsides to this beyond merely the potential speed cost in using pointers and optimization issues mentioned above.

1 comments

Yes, I agree, it's about facilitating run-time configuration and testing. Not sure I agree with the increasing of code complexity though. Maybe there's an aspect of code complexity that increases with dependency injection. I personally feel that code complexity more correlates with explicit branches, something that I usually eliminate using DI or polymorphism. And yeah, any way of writing code has it's downsides and upsides, just a matter of finding balance.
Yeah absolutely; re: code complexity, if its only one level deep its not really an issue, but you get into nasty situations when you have recursive calls taking place.

A <--- B, C

C <--- D

D <--- E, F

Now if you want to have function G that calls A, it needs to have a call like this:

void G (void E, void F, void D, void B, void C) { A(B, C(D(E, F))) }

(where void --> what ever function pointer)

Not pretty. There are totally ways around this to do with grouping injected values or separating apis so the chain is never deeper than one or two, but it really does lead to some hideous code if you're not careful. :)

As a caveat to what I said as well though, I will admit: what I said only applies if you're on a sane system that lets you use dynamically linked libraries. If you're on a stupid OS that has artifical restrictions (I'm looking at you iOS) this is probably actually not the worst way to go for cleaner code, if you're writing plain C.

Well written! I think that potentially hideous code, putting together groups of injected code is one of the hardest type of component get right. My background is in embedded and mobile so I usually expect a stupid OS or perhaps not even an OS at all (or perhaps writing part of the OS). Artificial restrictions is just silly tough.