These are all important traits, and I trust that distage is one way of implementing the above requirements.
However, there’s always some tradeoffs. I prefer to have compile-time verification of the object graph, explicitly declare dependencies, and use basic language mechanism (constructors,
new, module-traits) to do the wiring.
That comes at the expense of a bit more code if you want to e.g. switch components using a commandline flag, but it’s a matter of a simple
if. Drawing graphviz file indeed isn’t possible, but again at the cost of an overall leaner approach.
I suspect that both of our approaches to DI might be valid, with their strengths and weaknesses, and that we might agree to disagree on the “best” one :)