This might be a beginners question, the question is related to understanding why do we need injecting the services into components.
1] Why do we need to inject the service to each component when we could just create a static method and it will return the same output and we're really not going to need to keep writing extra code for injecting these services?
Let's say I have an authentication service like the one below with the normal convention:
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import { GlobalConfig } from "../global-config";
// Models
import { UserModel } from "../models/user-model";
@Injectable()
export class AuthenticationService {
constructor(private http: Http) { }
authenticate(user: UserModel): Observable<UserModel> {
let userObject = this.http.post(GlobalConfig.getUrlFor('authentication'), user)
.map((response: Response) => {
let responseJSON = response.json();
let userObj = <UserModel>{
UserId: responseJSON.UserId,
FirstName: responseJSON.FirstName,
LastName: responseJSON.LastName,
FullName: responseJSON.FullName,
Email: responseJSON.Email,
UserName: responseJSON.UserName,
Password: responseJSON.Password
};
return userObj;
});
return userObject;
}
}
And in the view model, i would use it like that :
First: Inject the service
constructor(private authService: AuthenticationService) {}
Second: Call it
login() {
this.authService.authenticate(this.user)
.subscribe(
p => {
GlobalConfig.baseUser = p;
localStorage.setItem('user', JSON.stringify(p));
this.router.navigate(['/dashboard']);
},
e => {console.log('Error has Occured:', e); }
);
}
But If I in the first place made that authenticate method in the authentication service Static all I would have done is the following:
login() {
AuthenticationService.authenticate(this.user)
.subscribe(
p => {
GlobalConfig.baseUser = p;
localStorage.setItem('user', JSON.stringify(p));
this.router.navigate(['/dashboard']);
},
e => {console.log('Error has Occured:', e); }
);
}
And I wouldn't have needed to inject it or write in extra necessary work.
I know Service injection is the known good practice but I really don't understand why. Appreciate if someone would explain more to me.
ES6 includes static members and so does TypeScript. The static members of a class are accessed using the class name and dot notation, without creating an object e.g. <ClassName>. <StaticMember>. The static members can be defined by using the keyword static.
The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service. The injector is the main mechanism.
Marking a class with @Injectable ensures that the compiler will generate the necessary metadata to create the class's dependencies when the class is injected. The following example shows how a service class is properly marked so that a supporting service can be injected upon creation.
Static methods of a class, unlike instance methods, are visible on the class itself and they are not an instance of it. Typically, when we talk about a static method, it takes input from the parameters, performs actions on it, and returns a result independently of your application.
Dependency injection provides much more flexibility and makes your application parts more independent. One case where I personally was burnt by static method — I developed a library and some projects made of multiple sub projects used different minor versions of my lib. There were no breaking changes between those and dependency injection would work just fine, injecting the first injectable that Angular picked up, however static method is defined on a specific class so you end up with 2 different methods from 2 different versions.
One very helpful feature of dependency injection is tokens — you can provide different things to different places that suit specific needs but all follow particular interface. Example being custom controls with ControlValueAccessor or abstractions that combine multiple components — if you want to create a directive that you can use with multiple components you can do so by injecting a token in it and providing that token inside all suitable components of yours.
Overall, there is plenty of neat features in dependency injection that are just not possible by plain static methods and static methods have drawbacks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With