Да, IoC контейнер - это вполне себе один из вариантов реализации DI. Позволяет вынести решение об используемой реализации утилит на самый верх всей иерархии кода. Через него разарботчик может подменить реализацию утилиты для сколь-угодно глубоко вложенного кода, который находится в сторонней библиотеке. Лишь бы эта библиотека использовала тот же самый IoC контейнер, что достигается использованием общего DI фреймворка.