I gave up on dependency injection frameworks a while ago. Now there's just some "wiring" code somewhere that wires up the components. It's small (one statement per component), trivial to write, easy to understand, and makes any kind of customisation easy (disabling whole subsystems under config, having alternative implementations for subsystems, etc), because it's just code.
It's also testable! The setup code is factored in such a way that it's harmless to run (eg sockets aren't opened during wiring), and it does all the config parsing and resolution and so on. So i have a suite of tests which run it, and then do some trivial checks like "all the necessary config is available", "handlers are defined for all the market data we subscribe to", etc. They've caught a bunch of schoolboy errors which would otherwise only have been found in staging.
I think anyone arguing for frameworks should spend some time making a serious attempt at frameworkless dependency injection. The frameworks are really doing so little for you, at occasionally horrendous cost.
> I think anyone arguing for frameworks should spend some time making a serious attempt at frameworkless dependency injection. The frameworks are really doing so little for you, at occasionally horrendous cost.
That is what I did, and decided a DI framework was much better. If you have a single scope, like singletons, its pretty easy to do the wiring manually. If not, then you see very quickly that your scope management code and rewiring of same things at different layer quickly becomes tedious, error prone (becoming out of sync with another wiring), boilerplate.
Passing a single "context" struct/class/whatever into everything basically solves DI. I can see using a framework for this, but it doesn't seem necessary.
Furthermore, this enables creating sub-contexts (like run this operation but with this different configuration) which is something almost impossible to do with DI frameworks.
Yeah, it's weird how such heavy frameworks often end up lacking basic features like this. That's like the first thing I'd look up how to do after the basic tutorial.
> The setup code is factored in such a way that it's harmless to run (eg sockets aren't opened during wiring
The other side-benefit of doing this is it can become much easier to hot reload components, since you just call the Stop / Start methods of just those components.
It's also testable! The setup code is factored in such a way that it's harmless to run (eg sockets aren't opened during wiring), and it does all the config parsing and resolution and so on. So i have a suite of tests which run it, and then do some trivial checks like "all the necessary config is available", "handlers are defined for all the market data we subscribe to", etc. They've caught a bunch of schoolboy errors which would otherwise only have been found in staging.
I think anyone arguing for frameworks should spend some time making a serious attempt at frameworkless dependency injection. The frameworks are really doing so little for you, at occasionally horrendous cost.