How to add providers to Injector dynamically?

本秂侑毒 提交于 2020-06-10 02:57:09

问题


Each component can specify new Providers using its providers property in ComponentMetadata.

Is there a way to specify providers dynamically from, say, constructor of the component?


回答1:


I've done it in the bootstrap part.

bootstrap(AppComponent,[
    provide( RequestOptions, { useClass: DefaultRequestOptions } ),
    provide(Http, { useFactory:
        function(backend, defaultOptions) {
            return new Http(backend, defaultOptions); },
        deps: [XHRBackend, RequestOptions]}),
]);

I'm guessing it can be done in a component too:

https://angular.io/docs/ts/latest/api/http/Http-class.html

You make it dynamic by adding decisions into the factory function instead of just returning the same object.




回答2:


I used useFactory to determine what class will be used for provide. I share for whom concern.

In component ts

@Component({
    selector: 'app-chart',
    templateUrl: './chart.component.html',
    styleUrls: ['./chart.component.scss'],
    providers: [
        { provide: DateTimeAdapter, useClass: MomentDateTimeAdapter },
        { provide: OWL_DATE_TIME_FORMATS, useValue: CUSTOM_FORMATS },
        { provide: OwlDateTimeIntl, deps: [SettingService],
            useFactory: (settingsService) => settingsService.getLanguage()
        }
    ]
})

In service ts get class instance

@Injectable()
export class SettingService {
    public getLanguage(){
       return this.translate.currentLang == "ko" ? new KoreanIntl() : new DefaultIntl;
    }
}



回答3:


Below are 3 broader steps you need to follow to implement dynamic providers. Please note i have commented many part of the code so that we focus on the main answer. If you want to see detailed step refer this Angular tutorial

Step 1 :- Create the collection of the providers

Create the collection and you can use the push method to add DI objects dynamically.

var providerscoll:any = [];
providerscoll.push({ provide: "1", useClass: DialogLogger });
providerscoll.push({ provide: "2", useClass: ConsoleLogger });

Step 2 :- Provide the providers collection in "NgModule" .

Please see the Square bracket syntax.

@NgModule({
    // code removed for clarity
    providers: [providerscoll]
})
export class MainModuleLibrary { }

Step 3 :- Get the Injector object in constructor

Get injector object in the constructor using DI and you can then look up using the "Get" method and the token. So if you provide "1" then you get something and if you provide "2" you get something.

// code removed for clarity
import {  Injector } from '@angular/core';
// code removed for clarity
export class CustomerComponent {
constructor(public injector: Injector){
        this.logger = this.injector.get("2");
    }
}


来源:https://stackoverflow.com/questions/34712171/how-to-add-providers-to-injector-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!