1

I am wondering what the difference is between these two examples:

export class EditorComponent {

  constructor(
      public _entryService: EntryService
  ){
      console.log(this._entryService.entryData.properties);
   }

}

export class EditorComponent {

  _entryService;

  constructor(){
     this._entryService = new EntryService;
     console.log(this._entryService.entryData.properties);
  }

}

Is there any practical difference between the two?

I anticipate that there may be some gaps in my knowledge of basic theory here- any pointers in a direction that will help me educate myself would be appreciated- thanks!

Inigo
  • 8,110
  • 18
  • 62
  • 110
  • 2
    `injecting` means **single instance**. `instanctiating` means **creating multiple instances**. For `injectable()` services it is a bad practise to instantiate. you might end up facing [**cannot resolve all parameters**](https://stackoverflow.com/questions/44996095/angular2-ionic2-cant-resolve-all-parameters-for-gameserviceprovider/44996310#44996310) error – Aravind Sep 16 '17 at 15:26
  • Injecting a service isn't always resulting in a single instance. For example providing a service inside the provider section of a shared module will result in a new instance of the service each time the module is imported into another module unless it's defined via `NgModuleWithProviders` and imported in the application's root module via static method ([DOCS](https://angular.io/guide/ngmodule#why-userservice-isnt-shared)). – cyr_x Sep 16 '17 at 15:35
  • 1
    @cyrix You're misinterpreting the documentation. The behaviour you're describing refers to the case when another module gets its own injector, i.e. lazy loaded module. This won't happen if a module isn't lazy-loaded. – Estus Flask Sep 16 '17 at 15:56
  • I missed to write the word lazy-loaded. You're absolutly right, if your shared module is imported by another **lazy-loaded** module, a new instance is created. ("module is imported into another **lazy-loaded** module") – cyr_x Sep 16 '17 at 15:59
  • Thanks, Aravind- what I suspected. That clarifies it, thanks. – Inigo Sep 16 '17 at 16:19

1 Answers1

2

The equivalent of this._entryService = new EntryService is a provider in component definition:

@Component({ ..., providers: [EntryService] })
export class EditorComponent {
  constructor(
      public _entryService: EntryService
  ){}
}

This will create new EntryService instance per each component instance.

If no provider belongs to component injector, it will be retrieved from parent injector (likely root injector) and will result in single instance of EntryService provider:

@Component({ ..., providers: [] })
export class EditorComponent {
  constructor(
      public _entryService: EntryService
  ){}
}

The only case when new EntryService is desirable is when class constructor accepts non-DI arguments (like shown in this example).

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • EntryService isn't a singleton in your case, to make it a singleton, you have to implement it as a singleton. – cyr_x Sep 16 '17 at 15:48
  • @cyrix It is a singleton within a single injector. If the provider isn't defined in a component and retrieved from parent injector where it was defined, it will be a singleton. That's what the answer says. – Estus Flask Sep 16 '17 at 15:53
  • That doesn't make the service class a singleton class, you could still create new instances yourself, which is against the singleton pattern. What you're trying to say is that only one instance is created and is used by each component within a module. – cyr_x Sep 16 '17 at 15:57
  • @cyrix EntryService class isn't a singleton. EntryService provider is. *singleton pattern is a software design pattern that restricts the instantiation of a class to one object* - this is what Angular injector does in this case. I don't see a problem with nomenclature here, as long as readers understand what is this all about. – Estus Flask Sep 16 '17 at 16:07
  • That's why i upvoted it, but from my point of view it's not clear that you're refering to the provider as a singleton. – cyr_x Sep 16 '17 at 16:15
  • Thanks for you answer, which I'll probably end up accepting. Please don't use acronyms in a layman's answer though... "non-DI arguments", sorry, what does "DI" stand for? thanks :) – Inigo Sep 16 '17 at 16:22
  • @Inigo It stands for dependency injection. – Estus Flask Sep 16 '17 at 16:24
  • @cyrix Thanks for bringing the attention to it. – Estus Flask Sep 16 '17 at 16:26