20

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.

Willy
  • 3,506
  • 3
  • 22
  • 35
  • 4
    If you care about testability and decoupling, never use static methods. https://en.wikipedia.org/wiki/Inversion_of_control. Angular based their architecture on DI, to make it easy to build your code according to these principles. – Günter Zöchbauer Sep 10 '17 at 15:36
  • 1
    The chapter on DI of the official angular documentation also has a long introduction explaining "Why DI": https://angular.io/guide/dependency-injection#why-dependency-injection – JB Nizet Sep 10 '17 at 15:42
  • Possible duplicate of [Typescript and AngularJS - Static methods vs services](https://stackoverflow.com/questions/39011788/typescript-and-angularjs-static-methods-vs-services) – Sylvain Sep 27 '17 at 18:58

1 Answers1

7

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.

waterplea
  • 3,462
  • 5
  • 31
  • 47