Dependencies are defined in a single place instead of throughout your app, and components that depend on other components can easily request them without having to understand the full dependency chain. “Car” can request “engine” without knowing that “engine” depends on “pistons.”
The tight coupling means it’s not possible to have a developer working on engines while another is working on pistons. (For that matter, you can’t easily make an empty set of objects as placeholders for pistons while you work on engines). The components create their own dependencies so there is no way to effectively test them without dependencies.
The solution is to bring in an IoC (short for Inversion of Control) container to manage Dependency Injection. There are many types of containers, but here’s how they typically work: You get one global instance of the container (you can have multiple containers but we’ll stick with one to keep it simple)
After you are comfortable with DI and IoC, you can dig deeper to see how I created the container. The library does many things but, in a nutshell, you pass it a label and a constructor function to register a component. If you have dependencies, you pass an array with those dependencies.
The first one is a service which makes Ajax requests and the second one is a router. We have another function which needs these modules. And to make the things a little bit more interesting the function needs to accept one more parameter. Sure, we could use the above code, but that’s not really flexible.
What can you do with dependency injection in angular?
For a more advanced solution, take a look at Angular’s dependency injection. You can define different registrations (called Providers) such as types (via TypeScript), hard-coded values and even factories that are functions that return the desired value. You can also manage lifetime or scope, for example: