In my field, DIP is just too impractical in many cases. The cost of virtual dispatch for the CPU in our lowest-level modules (memory allocators, core data structures, etc), even ignoring the extra programmer overhead of creating abstract interfaces and testing them with mock objects, is just too much to maintain a competitive performance advantage in an industry where users always want more. This isn't an opinion formed absent measurements. It's not a hunch.
Low-level concretes are usually performance-critical concretes in our cases (computer graphics including things like image processing), and we usually can't afford to abstract them in any way that imposes runtime costs. It would certainly be extremely convenient if I could abstract the low-level details of an image, like its pixel format, away in favor of dynamic dispatch just to do things like set or get a specific pixel, but we simply can't afford it from a runtime perspective... or even the programmer overhead if we tried to abstract all these things with static polymorphism and used elaborate code generation techniques with something like C++ templates. In the zealous pursuit of eliminating logical redundancy for the latter case, we'd skyrocket build times and the expertise required to maintain code with the likes of recursive metatemplate programming that combines with SIMD intrinsics even with the absence of runtime costs. If an image uses 32-bit single-precision floating-point for its channels, we can't abstract away such details without major costs. It would certainly be so much simpler if we could, but we simply can't without our competition leap-frogging ahead of us in terms of user interactivity and response.
I used to be a C++ meta-template programming zealot so eager to keep being able to use abstractions without runtime costs while touting the idea that these abstractions were "cost-free" back in the 90s when this stuff was just starting to get really popular. All I did was end up causing tremendous grief for my team imposing a cost that I was oblivious towards until it was inflicted upon me by others later on.
There are no such things as "cost-free" abstractions in my experience if "cost-free" extends to both programmer and runtime overheads combined where a net positive in one is not allowed to produce a net negative in the other. There are cheap abstractions. There are ones where the savings in one area more than compensate for the costs in the other. But there aren't any free ones in my experience, or at least not ones we have to maintain ourselves.
We have a tendency to want to future-proof our software but a future-proofing mindset often yields code that is even more costly to change should it fail to meet future design requirements. YAGNI might be the most important of the software principles, because following it, even when we discover something we do need that we didn't have, tends to be much less costly than discovering we built all sorts of things, especially abstractions, that we didn't actually need or were too generalized and insufficiently tailored for the problem at hand.
So in my opinion at least, and keep in mind my bias given my field and domain because I'm never speaking for everybody in any one of my opinions, is "no". DIP is actually one of the most useless principles in my blunt opinion, although that's speaking only with respect to the design requirements I work with. We simply can't afford to always sandwich abstract interfaces between high-level modules and low-level ones. We can't even afford to do it most of the time. We can usually afford it at the mid to high-level end of the spectrum, and obviously, we can abstract things like file I/O with trivial cost since the functions involved make things like virtual dispatch trivial in comparison.
Client
,Invoice
andProduct
sinceInvoiceLine
is highly connected toInvoice
? I think I'm not understanding something