Specify Service Providers in Angular 2

I'm trying to use the Angular 2 DI system to automatically handle the dependencies of my services. I would like to use annotation for the service itself, rather than using the second bootstrap() parameter to specify all injection services.

What i got

Low level service:

services/role-store.ts

 export class RoleStore { constructor() { // Initialize roles } getById( id ) { // accepts id, returns role object } }; 

A high-level service, which depends on a low-level service:

services/user-store.ts

 import {Injectable} from 'angular2/angular2'; import {RoleStore} from './role-store.ts'; @Injectable() export class UserStore { constructor( roleStore: RoleStore ) { this.roleStore = roleStore; // Initialize users } roleForUser( user ) { let role = this.roleStore.getById( user.roleId ); return role; } }; 

A component that depends on a high-level service:

components/user-dir.ts

 import {Component, View, CORE_DIRECTIVES} from 'angular2/angular2'; import {UserStore} from '../services/user-store'; @Component({ selector: 'user-dir', bindings: [UserStore] }) @View({ template: '<!-- inline template -->', directives: [CORE_DIRECTIVES] }) export class UserDir { constructor( data: UserStore ) { this.userStore } // other methods... } 

Root component for bootstrap:

app.ts

 import {Component, View, bootstrap} from 'angular2/angular2'; import {RoleStore} from './services/role-store'; import {UserDir} from './components/user-dir'; @Component({ selector: 'app' }) @View({ template: '<user-dir></user-dir>', styleUrls: ['./app.css'], directives: [UserDir] }) class App {} bootstrap( App, [RoleStore] ); 

Problem

bootstrap( App, [RoleStore] ) works, but I would prefer an annotation in user-store.ts that tells Angular to insert RoleStore .

Something like @Provide( RoleStore ) class UserStore {} .

Any tips?

+8
angular
source share
2 answers

providers for services are not supported https://github.com/angular/angular/issues/5622

Instead, you can create arrays of providers that are exported as “modules”

 export const ROLE_STORE_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [RoleStore]; 

and then in modules that use the RoleStore service

 export const PARENT_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [ParentService, RoleStore]; 

and then use it in bootstrap

 bootstrap(AppComponent, [PARENT_PROVIDERS]); 

I admit that this is not what you asked for, but the closest I have found so far.

+4
source share

You always need to register providers at some level, in your case it would be more appropriate to register them at the component level to indicate the dependency, and not at the entire application level. Something like that...

 @Component({ selector: 'user-dir', template: '<!-- inline template -->', directives: [CORE_DIRECTIVES] providers: [UserStore, RoleStore] }) export class UserDir { constructor( data: UserStore ) { this.userStore } // other methods... } 

This is the official way to make sure that dependencies are manually recorded in the Angular 2 DI engine as much as possible.

In this case, you will need to write your own compiler time / runtime (init), which will move the code, collect all @Injectable services and register them in the context of Angular 2 (using providers )

0
source share

All Articles