Reading this article reminded me that DI has a lot of advocates, but I've never heard a compelling reason to use it in most codebases.
Reading this article reminded me that DI has a lot of advocates, but I've never heard a compelling reason to use it in most codebases.
Say in rust, you have some struct backing a trait. But your implementation of the trait can also have a variety of options which are parameterized by some other trait. You end up with a generic struct: that is all dependency injection is. Every generic struct in rust is an example of dependency injection.
Instead, dependency injection frameworks help people instantiate large dependency graphs with some lifecycle management. Those I am a bit of the take it or leave it opinion.
Sorry for being cynical. I can't help it.
Unfortunately, there are many of those.
What I often find is that management in organizations rewards these people because they get quick results. The cost to the customer and the team is well hidden until it’s too late.
The alternative to DI is keeping dependencies in a global state (global variables, singletons, whatever) and that is a maintainability nightmare for any codebase above a certain size. I don't think that it matters if the language is OOP or not, the issue is the same.
Regardless of what the article says, mocking in tests is easier. As you’re only depending on injected classes, you just mock a class and inject it in a test.
Like any architectural decision “it depends”. But I think it scales well, enforces modularity, automates construction logic (which can be huge) and is quite nice to work with generally.
The same reason as in OO languages. Clean separation of startup and runtime. Testability. Ability to avoid duplication and make changes in one place.
> What techniques do you use to make the level of indirection feel like a help, rather than a hindrance, in your codebase?
Separation of concerns/responsibilities always involves indirection. Using something like a free monad would be more indirection. I can't really give any useful advice beyond "factor your app well" and "split concerns/responsibilities at points that make sense"
I suspect it is because Typescript doesn't properly support prototype function assignment, which makes scoped injection painfully ugly.
* Minimizing non-local state
* Keeping things testable
* Keeping code reusable without having to find and copy a lot of other code from a codebase/refactor completely
Note: I am not talking about DI frameworks here, because I don't like them.