'Injectable on service is mandatory in angular 12

I'm trying to understand @injectable vs @Inject. Found many articles on it, and its best practice to use @Injectable on Service.

But I believe these two snippet(UserService) should behave same.

import { Inject, Injectable } from "@angular/core"

export class NewUserService {
  constructor() {
    console.log('NewHerorService')
  }
}

export class UserService {
  constructor(@Inject(NewUserService) private newUserService: NewUserService) {
    console.log('test')
  }
}

**VS** 

@Injectable()
export class UserService {
  constructor(private newUserService: NewUserService) {
    console.log('test')
  }
}

And this is working fine(both behaving same) in Angular 8.

But the same thing in Angular 12 giving error:

Error in src/app/app.module.ts (15:15) The class 'UserService' cannot be created via dependency injection, as it does not have an Angular decorator. This will result in an error at runtime.

Either add the @Injectable() decorator to 'UserService', or configure a different provider (such as a provider with 'useFactory').

Sample links Angular 8 Angular 12

Update: After digging some more into it, found if I set "enableIvy": false in .tsconfig.json of angular 12 version, then it not throws any error and works same as angular 8.

But still don't know why?



Solution 1:[1]

The difference between Inject and Injectable:

Inject

The Inject decorator allows you to define what provider do you want to be used for the injection. In the example bellow (taken from Angular Dependency Injection page), the BROWSER_STORAGE is used as the provider for the Storage service.

import { Inject, Injectable, InjectionToken } from '@angular/core';

export const BROWSER_STORAGE = new InjectionToken<Storage>('Browser Storage', {
  providedIn: 'root',
  factory: () => localStorage
});

@Injectable({
  providedIn: 'root'
})
export class BrowserStorageService {
  constructor(@Inject(BROWSER_STORAGE) public storage: Storage) {}
}

Injectable

The Injectable decorator allows to define a class as Injectable, meaning you can Inject it on another component or service. Note the if you inject the service like

constructor(private storage : Storage){}

The default behavior of Angular is to instanciate using new Storage()

To learn more about providers see the Angular Dependency providers page

Feel free to ask for clarification if needed!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Manuel Tomás