在Angular 2中指定服务的提供者

Tyl*_*ich 8 angular

我正在尝试使用Angular 2的DI系统来自动处理我的服务的依赖性.我想在服务本身上使用注释,而不是使用第二个参数bootstrap()来指定所有可注入服务.

我得到了什么

低级服务:

services/role-store.ts

export class RoleStore {
  constructor() {
    // Initialize roles
  }

  getById( id ) {
    // accepts id, returns role object
  }
};
Run Code Online (Sandbox Code Playgroud)

依赖于低级服务的高级服务:

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;
  }
};
Run Code Online (Sandbox Code Playgroud)

依赖于高级服务的组件:

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...
}
Run Code Online (Sandbox Code Playgroud)

引导程序的根组件:

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] );
Run Code Online (Sandbox Code Playgroud)

问题

bootstrap( App, [RoleStore] )有效,但我宁愿有一个注释user-store.ts,告诉Angular注入RoleStore.

有点像@Provide( RoleStore ) class UserStore {}.

有什么建议?

Gün*_*uer 5

providers不支持服务https://github.com/angular/angular/issues/5622

您可以做的是创建像“模块”一样导出的提供程序数组

export const ROLE_STORE_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
    [RoleStore];
Run Code Online (Sandbox Code Playgroud)

然后在使用 RoleStore 服务的模块中

export const PARENT_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
    [ParentService, RoleStore];
Run Code Online (Sandbox Code Playgroud)

然后在引导程序中使用它

bootstrap(AppComponent, [PARENT_PROVIDERS]);
Run Code Online (Sandbox Code Playgroud)

我承认这不是你要的,而是我目前找到的最接近的。


tom*_*jan 0

您总是必须providers在某个级别上注册,在您的情况下,在组件级别上注册它们更有意义,以便在此处指定依赖项,而不是在整个应用程序级别上指定。像这样的东西...

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

这是官方的做法,将依赖项手动注册到 Angular 2 DI 机制中最具体的级别。

话虽如此,您需要编写自己的编译时/运行时(init)工具,该工具将遍历代码收集所有 @Injectable 服务并将它们注册到 Angular 2 上下文中(通过使用providers