Angular2 providers, view providers and "singletons"

The following is an illustration of how providers act through the angular application, or the components tree. You can control their action scope by using providers or viewProviders so that multiple sibling components share the same instance of that provider.

Using Angular2 beta 8

This is my provider for example purpose. It’s an EventEmitter.

@Injectable()
export class MyProvider extends EventEmitter {
  constructor() {
    super()
  }
}

When you declare providers inside a component, they will be instantiated (here new MyProvider) for the same component.

For example, this component will have it’s own instance of MyProvider:

@Component({
selector: 'my-foo',
templateUrl: 'foo.html',
providers: [MyProvider]
})

export class MyComponent {
  constructor(private _myProvider: MyProvider) {
    _myProvider.subscribe(event => this.gotcha())
  }

  function gotcha() {
    console.log('Hello you')
  }
}

The EventEmitter can be really useful to share real time events between multiple components.

In this case, if I do the same injection for 2 different components, they’ll not share the same instance but the’ll have their own. This means that subscribe will listen to events belonging to the component’s provider instance, and therefore will not be able to share events with it’s peers.

I hear you coming with the “singletons” word. I don’t really agree to call them singletons here because Angular2 allows us to control their action scope. By definition, a singleton will have one and only one instance, here we could have more than one, acting on different components.

Wait what? How?

Using viewProviders!

Basically a view provider is a provider instantiated once for the view, where the view injection scope is it’s child components.

In the following plunkr, the EventEmitter is added to the viewProviders of the parent component. above and below, two different components, are sharing the same instance. Note that you should not register the provider on child components or you’ll have a new instance of the provider (see the MiddleComponent):

See also this Google groups post where the provider is also registered at the boot level. It then will be a “real singleton”.