Advent Calendar #15 - Angular Dependency Injection

Advent Calendar #15 - Angular Dependency Injection

What is dependency injection generally?

The term dependency injection is strongly related to the principle of inversion of control. It states, that not a function solely should do all the work to accomplish a goal. Rather it should accept dependencies to make it more configurable.

What has Angular to do with it?

Angular is not only a library, like React. It is a full-featured Framework that takes care of:

  • rendering

  • dependency injecting via constructor injection

  • routing

  • etc.

Once I understood the dependency injection part of Angular, I stepped up my Angular game and never got an unresolved R3InjectionError again.

While it might be confusing at first, we will look through it.

What is a provider?

An Angular provider is just a class that has been marked as injectable via the @Injectable flag. It can be passed to constructors of other injectables, or components.

Providers array

The providers: [] array can be found on:

  • modules

  • and components

You HAVE TO pass the actual providers to this array. Like this

@NgModule({
  providers: [UserRepository]
})
class UserModule {}

Injector

The angular injector resolves the dependencies of all classes passed to the provider array.

Most of the time, you do not need to interact with it directly. It is taken care of in the background.

R3InjectionError

That means the following code can be resolved via the injector

@Injectable()
class UserRepository {
  constructor() {}
}

while without the @Injectable annotation this won't work.

class UserRepository {
  constructor() {}
}

If you were to inject the UserRepository without the @Injectable() annotation, you will get a R3InjectionError.

@Component(/*..*/)
class UserProfileComponent {
  constructor(userRepository: UserRepository) {}
  // will only work, if the UserRepository, has the
  // Injectable annotation and the UserRepository is
  // added any of the providers array.
}

Read more