Angular is a frontend development framework used for building single-page client applications using HTML and Typescript. It is written in Typescript.
Dependencies are one type of object or service which is used by a class to perform its function. Dependency injection (DI) is a design pattern in which a class requests dependencies from external sources rather than creating them. Flexibility and modularity can be increased if we use dependency injection in our angular application.
An angular provider is one type of object declared in Angular so, we can inject it within the constructor of our components, directives, and also in angular instantiated classes. Also, we can say that the Angular Provider is an instruction that expresses how an object for a certain token is created.
Angular service is a particular type of provider that is declared with its class name. The Angular Provider is an array of providers. We can uniquely identify each provider using a token in the Providers Array. For locating the provider, we use tokens. There are three types of the token. Type Token, string token, and Injection Token. We have four ways to create dependency: which are Class Provider (useClass), Value Provider (useValue ), Factory Provider ( useFactory ), and Aliased Class Provider ( useExisting).
We need to register dependency in the Providers metadata to Provide an instance of the dependency. See the following syntax it has two properties.
providers:[{provide:EmployeeService, useClass: EmployeeService}]
Provide
The first property is Provide which holds the Token. The Injector uses the token to locate the provider in the Providers array. The Token can be a type, a string, or an instance of InjectionToken.
Provider
The second property is the Provider definition object. Provider tells how to create the instance of the dependency to the angular. We have four different ways in angular for creating the instance of the dependency.
The Injector keep an internal collection of token-provider in the Providers array. The token works as a key to that collection. For locating provider Injector use that Token (key).
The Dependency Injection Token are type, a string or an instance of InjectionToken.
Type Token
In this, we can inject type as the token.
For Example, we would like to inject the instance of the EmployeeService, we will use the EmployeeService as the token as shown below
providers :[{ provide: EmployeeService, useClass: EmployeeService }]
The EmployeeService is then injected into the component file by using the following code.
class ProductComponent { constructor(private EmployeeService : EmployeeService ) {} }
String token
We can use a string to register the dependency. This is useful when the dependency is a value or object, which is not represented by a class.
Example
{provide:'EMPLOYEE_SERVICE', useClass: EmployeeService }, {provide:'USE_FAKE', useValue: true }, {provide:'APIURL', useValue: 'http://SomeEndPoint.com/api' },
We can then use the Inject dependency using the @Inject method.
class ProductComponent { constructor(@Inject('EmployeeService') private empService:EmployeeService, @Inject('APIURL') private apiURL:string ) { }
Injection Token
We have face problem with string tokens like if more than one developer can use same string token in some part of an application.
To overcome this problem we can use the Angular provides InjectionToken class so we ensure that the Unique tokens are created. The Injection Token is created when a new instance of the InjectionToken class is created.
export const API_URL= new InjectionToken('');
Register the token in the providers array.
providers: [ { provide: API_URL, useValue: 'http://SomeEndPoint.com/api' } ]
It is then injected using the @Inject in the constructor of the service/component.
constructor(@Inject(API_URL) private apiURL: string) { }
The Angular Dependency Injection provides various types of providers.
Class Provider: useClass
When we want to provide an instance of the provided class then we use useClass.
The useClass looks for us to provide a type. So the Injector creates a new instance from the type and injects it.
UseClass Example
providers :[{ provide: EmployeeService, useClass: EmployeeService }]
In the above, example EmployeeService is the Token (or key) and it maps to the EmployeeService Class. Class name and token name both match in this case.
Switching Dependencies
You can provide a Fake class for Testing purposes as shown following example.
providers :[{ provide: EmployeeService, useClass: fakeEmployeeService }]
The above example shows how to switch dependencies.
Value Provider: useValue
When you want to provide a simple value then use the Value Provider useValue,.
The Angular will injects as it is which is provided in the useValue.
UseValue Example
In below example, we pass a boolean value using token USE_FAKE.
providers :[ {provide:'USE_FAKE', useValue: true}]
We can inject it into the AppComponent using the @Inject
export class AppComponent { constructor( @Inject('USE_FAKE') public useFake: string ) {}
We can pass an object. We can use Object.freeze to freeze the value of the configuration, so others cannot change it.
const APP_CONFIG = Object.freeze({ serviceURL: 'www.employeeUrl.comapi', IsDevleomentMode: true });
Register it.
providers: [ { provide: 'APP_CONFIG', useValue: APP_CONFIG } ]
Inject it as shown below
export class AppComponent { constructor( @Inject('APP_CONFIG') public appConfig: any ) {} }
You can also provide a function
providers: [ { provide: 'FUNC', useValue: () => { return 'hello'; } } ]
The Injector injects the function as it is. We need to invoke the function empFunc() to get a value from it.
export class AppComponent { constructor( @Inject('FUNC') public empFunc: any ) { console.log(empFunc()); } }
Factory Provider: useFactory
The Factory Provider useFactory expects a function. It injects the returned value and invokes the function. We can also add optional using deps array to the factory function.
UseFactory example
Consider the use case where we want to inject either EmployeeService or FakeEmployeeService based on the value for USE_FAKE. Also, one of the services (EmployeeService ) requires another service (LoggerService). Here, we need to inject USE_FAKE and LoggerService into our factory function.
providers: [ { provide: LoggerService, useClass: LoggerService }, { provide: 'USE_FAKE', useValue: true }, { provide: EmployeeService, useFactory: (USE_FAKE, LoggerService) => USE_FAKE ? new FakeEmployeeService() : new EmployeeService(LoggerService), deps: ['USE_FAKE', LoggerService] } ]
We pass all the dependencies as the argument to the factory function. The injector uses the deps array as a third argument to resolve the dependencies and inject them.
useFactory: (USE_FAKE, LoggerService)
inside the factory function, we either return FakeEmployeeService or EmployeeService depending on the value of USE_FAKE
USE_FAKE ? new FakeEmployeeService() : new EmployeeService(LoggerService)
In the last option, we tell the Injector how to inject the dependencies of the Factory function itself.
deps: ['USE_FAKE', LoggerService]
Aliased Provider: useExisting
We can use Aliased Provider useExisting when we want to use the new provider in place of the old Provider.
UseExisting Example
providers: [ { provide: EmployeeService, useExisting: NewEmployeeService }, { provide: NewEmployeeService, useClass: NewEmployeeService },
In the above example, we map the EmployeeService to the NewEmployeeService token using useExisting Provider. This will return the NewEmployeeService whenever we use the EmployeeService .
The below example shows useExisting with string tokens.
providers: [ { provide: EmployeeService, useExisting: 'EMPLOYEE_SERVICE' }, { provide: 'EMPLOYEE_SERVICE', useClass: NewEmployeeService },
In this blog, we learned what is angular dependency provider. Types of dependency injector token and types of provider. Also, see how to register dependencies using the Angular Providers.
July 29, 2021
July 22, 2021
July 20, 2021
July 16, 2021
Well do everything we can to make our next best project!
Check out our most recent blogs
July 29, 2021
What is Angular? Angular is a frontend development framework used for building single-page client applications using HTML and Typescript. It is written in Typescript. What...
July 22, 2021
What is a Compiler? A compiler is nothing but a part of code that converts one programming language to another. If we talk about some simple programming languages like C, C++,...
July 20, 2021
What is binding in Angular? Binding in angular apps is the automatic synchronization of data within the model and view components. You can use data binding to define things...
Well do everything we can to make our next best project!