Angular2 "Services"如何将一个服务@inject到另一个服务(单例)?



如何将一个服务注入另一个服务?举个例子,我有一个需要另一个集合的集合(TeamCollection=>PlayerCollection)。目前,我只创建了两个独立的集合,并使用了以下内容:

import {PlayerCollection} from "<<folder>>/player";

但这需要我在Typescript中为我想要成为单例实例的每个服务编写自己的单例getInstance代码。

正确的方法是什么?我希望在我的Components中同时拥有两个singleton,并能够使用构造函数语法将一个服务@注入另一个服务,而无需创建singleton的新实例。

class TeamCollection {    
    constructor(@Inject(PlayerCollection): PlayerCollection) {}
}

因此,重读Pascal Precht的这篇精彩文章后:http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html

看到他评论:http://twofuckingdevelopers.com/2015/04/angular-2-singleton-service/

"使用Angular 2的DI注入的所有东西都已经是Singleton了。不需要这样的服务"

我进行了测试,现在我的发现既回答了我的问题,也让我对angular 2中的DI主题更加困惑。

请参阅以下代码:

team.ts

import {BaseCollection, BaseModel} from "./base";
import {PlayerCollection} from './player';
import {Injectable, Inject} from "angular2/angular2";
@Injectable()
export class TeamCollection extends BaseCollection {
    playerCollection: PlayerCollection;
    constructor(@Inject(PlayerCollection) playerCollection: PlayerCollection) {
        super();
        this.playerCollection = playerCollection;
    }
    create(data: Object): TeamModel {
        return new TeamModel(data);
    }
}

播放器.ts

import {BaseCollection, BaseModel} from "./base";
import {Injectable} from "angular2/angular2";
@Injectable()
export class PlayerCollection extends BaseCollection {
    create(data: Object): PlayerModel {
        return new PlayerModel(data);
    }
}

team.spec.ts

/// <reference path="../../typings.d.ts" />
//VERY IMPORTANT TO ALWAYS LOAD THESE
import 'zone.js';
import 'reflect-metadata';
import 'es6-shim';
import {TeamModel, TeamCollection} from "../../app/model/team";
import {PlayerCollection} from "../../app/model/player";
import {Inject, Injector} from "angular2/angular2";
describe('TeamCollection', () => {
  var teamCollection: TeamCollection;
  var playerCollection: PlayerCollection; 
  beforeEach(() => {
      var injector = Injector.resolveAndCreate([
        TeamCollection,
        PlayerCollection
      ]);
      teamCollection = injector.get(TeamCollection);  
      var injectorT = Injector.resolveAndCreate([
        PlayerCollection
      ]);
      playerCollection = injector.get(PlayerCollection);
  });
  it('should have a singleton PlayerCollection shared between all classes within the application', () => {
    console.log(teamCollection.playerCollection.uuId);
    console.log(playerCollection.uuId);
  });  
});

只要是同一个Injector(var injector)创建了两者,它们就共享相同的uuID。尽管当我使用第二个Injecter(var injectorT)时,uuID不同,这意味着创建了playerCollection的新实例。

现在我的问题是。如果我使用组件提供者语法:

@Component({
  selector: 'app',
  providers: [TeamCollection]
}) 
@Component({
  selector: 'player-list',
  providers: [PlayerCollection]
})

两者会共享同一个玩家集合,还是都会创建一个新实例?

编辑:只要它们是通过bootstrap(.., [ServiceA,ServiceB])方法创建的,它们就会执行

感谢pascal prechthttp://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

我发现拥有singleton服务的另一种方法是使用调用构造函数的getInstance()方法创建singleton模式,然后不将服务注入组件构造函数,而是将其作为静态类引用。你可以在这里查看样本代码:

在Angular 2&离子2

看看我的答案,我想是第二页。如果它对你有效,如果你能投赞成票,我将不胜感激。谢谢。

您需要确保以下内容:

只有在"提供"了服务之后,才能注入服务。在@组件中执行此操作很容易,因为您有providers[….]语句。

当你想为一项服务这样做时,你没有提供商:[]。。。。因此,唯一可以做到这一点的地方是在引导期间,您需要在中指定服务

boostrap(app, [
PlayerCollection,
Other,
More Services...

]

如果你深入研究文档,它特别指出你需要这样做。

最新更新