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.
}