Принцип: управление потоком и созданием зависимостей передается внешней среде (фреймворку, контейнеру), а не самому коду.
Вместо "класс сам создает зависимости" - "зависимости передаются извне". Конкретизация IoC - DI (Dependency Injection): внедрение зависимостей через конструктор, метод или свойство.
Плюсы: слабая связанность, тестируемость, гибкая замена реализаций.