Usable IoC actually can be implemented in just 4-5 classes. Yes, it won't be as powerful as Guice but for some (or a lot?) of applications it's probably enough.
You don't have to write interfaces to have dependency injection. You can and should declare all your dependencies as constructor parameters. If you create them inside a class you'll permanently lock the two together, thus making it a testability nightmare.
I think this is a good one. Most recent Java/C# systems would have a full IoC container, but have no dynamically selected components (which is how frameworks like Dagger -https://dagger.dev/ - can exist). A lot of runtime reflection/calculation gets done for something that can be known at compile time.