Angular2 “Services” how to @inject one service into another (singletons)?

后端 未结 3 1217
庸人自扰
庸人自扰 2020-12-28 14:20

How would I go about injecting one service into another? Let\'s for example say I have a Collection that requires another Collection (TeamCollection => PlayerCollection). Cu

3条回答
  •  不思量自难忘°
    2020-12-28 14:48

    So after re-reading this excellent post by Pascal Precht: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html

    And seeing him comment on: http://twofuckingdevelopers.com/2015/04/angular-2-singleton-service/

    "Everything injected using Angular 2’s DI is already a Singleton. No need for such a service"

    I went testing, and what I now found has both answered my question and made me even more confused about the topic of DI in angular2.

    See the following code:

    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);
        }
    }
    

    player.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

    /// 
    
    //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);
      });  
    });
    

    As long as it was the same Injector (var injector) that created both they share the same uuID Though when I use a second injector (var injectorT) the UUIDs are different meaning a new instance is created of the playerCollection.

    Now my question would be. If I use the component providers syntax:

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

    Would both share the same player collection or would both create a new instance?

    Edit: They do as long as they are created through the bootstrap(.., [ServiceA,ServiceB]) method.

    Thanks to pascal precht http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

提交回复
热议问题