At the heart of Angular, and one of its most powerful features as a framework, is how it brings dependency injection to Javescript.

What is Dependency Injection

Dependency injection (DI for short) is the concept of inversion of control (IOC for short), where you architect code in a way that you provide modules with other modules it needs to get some work done instead of having your modules go out and get other modules on their own. DI allows you to write decoupled code that is easier to unit test and to work with.

In the Angular world, this allows you to write these modular components and even services within your applications and simply tell Angular what you want to use and where you want to use them. Angular will handle constructing instances of those and sending them to your code where needed. The most common place you use DI is in your class constructors. So constructors for components, directives, pipes and services you write can leverage the way Angular does DI. You can simply declare types on your constructor parameters with some help from TypeScript and Angular will interpret that and make sure you receive an instance of that type when your constructors run.

You can also leverage DI through things like component metadata properties for directives and providers. You can even do some DI at the bootstrap phase of an Angular app, setting up your dependency graph when your app starts up and getting that delivered through all aspects of your app. And one of the powers of DI is the ability to replace a dependency at any phase of application code. Angular has support for this. So you can even do things like set up a dependency for a service at bootstrap and then replace that dependency with a different version of it for a specific component.

There's a ton of power you can get out of Angular's dependency injection framework.