I think you missed an understanding of the structure of IoC.
To answer your question
but is the link referencing the dependency?
Yes, but it is on a different level. IoC are dependencies between classes. Instead of using new Something() in your class, you provide a constructor that requires all dependent interfaces. Thus, the class does not have control, the implementation of which is passed to it. This is an inversion of control. An IoC container is just an aid to helping you manage your dependencies in a pleasant way.
Say you have an ICustomerNotificationService interface with an implementation, for example
public class MailNotificationService : INotificationService { IMailerService _mailer; ICustomerRepository _customerRepo; IOrderRepository _orderRepo; public MailNotificationService(IMailerService mailer, ICustomerRepository customerRepo, IOrderRepository oderRepo) {
So, if your application requests an instance of ICustomerNotificationServcie , the container indicates which specific implementations to take and tries to satisfy all the dependencies that the class requested.
The advantage is that you can easily configure all the dependencies in your boot logic and easily change the behavior of your application.
For example, during testing, you run an application with the implementation of IMailerService , which writes letters to a file and connects a real mail service in production mode. This would not be possible if you introduced a new constructor instead of as a constructor instead of MailerService .
A good IoC container can handle much more for you, like life cycle management, single player games, scan assemblies for the types you want to register, and much more. We based our entire plugin system on a Structural Map , for example.
You can take a look at this blog article and its second part .