Angular2 DI - initializing multiple different instances in the same constructor

前端 未结 3 1065
别那么骄傲
别那么骄傲 2020-12-06 02:48

I have an Angular2 DI question. Say I have a TestService and I want to use 2 different instances of this service inside the same component. If I simply add a pr

相关标签:
3条回答
  • 2020-12-06 03:11

    Given that there is finite amount of instances, the straightforward way may be:

    @Component({
        providers: [
            { provide: 'TestService1', useClass: TestService },
            { provide: 'TestService2', useClass: TestService }
        ]
    })
    export class TestComponent implements OnInit {
        constructor(
            @Inject('TestService1') private _testService1: TestService,
            @Inject('TestService2') private _testService2: TestService
        ) {}
        ...
    }
    

    Or OpaqueToken counterpart to avoid overriding services with the same string identifier:

    export const TestService1 = new OpaqueToken;
    export const TestService2 = new OpaqueToken;
    
    ...
    providers: [
        { provide: TestService1, useClass: TestService },
        { provide: TestService2, useClass: TestService }
    ]
    ...
    constructor(
        @Inject(TestService1) private _testService1: TestService,
        @Inject(TestService2) private _testService2: TestService
    ) {}
    

    It doesn't hurt DI in TestService constructor. And keeps the testability of TestComponent on par, both service instances can be mocked independently.

    0 讨论(0)
  • 2020-12-06 03:13

    You can inject a factory that returns a new instance every time you call it:

    @NgModule({
       providers: [{
          provide: 'testService', 
          useFactory: (/* TestService deps here like `http`*/) => 
            (/* params */) => new TestService(/* http */), 
          deps: [/* TestService deps here like `Http`*/ ]
        }]
    })
    
    
    @Component(...)
    export class TestComponent implements OnInit {
    
        constructor(@Inject('testService') private _testServiceFactory) { };
    
        ngOnInit() {
            console.log("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", this._testServiceFactory( /* params */).toString());
            console.log("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", this._testServiceFactory().toString());
        }
    }
    

    Plunker example (check the output in the browser console when you click the button)

    0 讨论(0)
  • 2020-12-06 03:18

    I would create a static method that returns new instance in the service, and inject it only one through DI in component. Something like:

    import {Injectable} from "@angular/core";
    
    @Injectable()
    export class TestService {
    
        public id: number = Math.random();
    
        public toString(): string {
            return "Id: " + this.id;
        }
        static init() {
          return new TestService();
        }
    }
    

    then in component:

    import {Component, Input, OnInit} from "@angular/core";
    import {TestService} from "../../services/test.service";
    
    @Component({
        providers: [TestService]
    })
    export class TestComponent implements OnInit {
        _testService1: TestService;
        _testService2: TestService;
    
        constructor(_testFactory: TestService) { 
           this._testService1 = _testFactory.init();
           this._testService2 = _testFactory.init();
        };
    
        ngOnInit() {
            console.log("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", this._testService1.toString());
            console.log("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", this._testService2.toString());
        }
    }
    
    0 讨论(0)
提交回复
热议问题