It's all about loose coupling.
Imagine you have a class foo that is dependant on class bar
public class Foo
{
public Foo(Bar bar)
{
}
}
Here we have to pass an instance of bar into the class to instantiate it. What happens if we want to have two differant implementations of Bar, one for interacting with a DB and one for testing?
Well we would create and interface IBar and use that instead, then we can use two concrete implementations.
Now consider that we have lots of complex dependencies in lots of classes which are being called in lots of places, if we wanted to change the implementation we would have to change the code in every place a an object implementing IBar is created, that could be a lot of work.
Instead we can use dependancy injection like this.
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IBar, Bar>();
Foo foo = myContainer.Resolve<Foo>();
Here the unity framework has inserted a Bar object into the Foo's constructor, if you changed the type registration in one place, you change how Foo objects will get resolved all over the place.
When you have complex dependencies that may change, DI is essential!