提供器的声明方式,常用的有3种
使用类:useClass
{ provide: MyService, useClass: MyMockService }
使用工厂:useFactory
使用工厂进行注入,就需要写一个返回任意对象的函数。
{ provide: MyComponent, useFactory: ()=>{
if(islogin){
return new MyLoggedComponent();
}
return new MyComponent();
}}
使用值:useValue
{provide:'API_URL',useValue:'http://my.api.com/v1'}
demo
编写一个工厂函数,根据随机数实例化服务1:StockService或服务2:Stock2Service
//app.module.ts
providers: [
{provide:StockService,useFactory:()=>{
let dev = Math.random() > 0.5;
if(dev){
return new StockService();
}else{
return new Stock2Service();
}
}},AnotherstockService]
因为之前StockService服务的构造函数中有注入其他服务AnotherstockService,所以在实例化时,需要传入实例化的参数
providers: [
{provide:StockService,useFactory:()=>{
let logger = new AnotherstockService();
let dev = Math.random() > 0.5;
if(dev){
return new StockService(logger);
}else{
return new Stock2Service(logger);
}
}},AnotherstockService]
那为什么使用useClass的provider不用传入参数呢,我猜想应该是angular通过useClass自动完成了这个过程。
接着,为了使我们的工厂参数中let logger = new AnotherstockService();
与AnotherstockService解耦,可以使用deps属性:
providers: [
{provide:StockService,useFactory:(logger:AnotherstockService)=>{
let dev = Math.random() > 0.5;
if(dev){
return new StockService(logger);
}else{
return new Stock2Service(logger);
}
},deps:[AnotherstockService]},AnotherstockService]
deps是个数组,对应useFactory中匿名函数的参数,如:deps中的第一个参数AnotherstockService,angular会找到名为AnotherstockService的token,实例化后赋值给useFactory匿名参数中的logger。
因此,省略了let logger = new AnotherstockService();
而其实,我们还可以增加个使用值的提供器
providers: [
{provide:StockService,useFactory:(logger:AnotherstockService,isdev)=>{
if(isdev){
return new StockService(logger);
}else{
return new Stock2Service(logger);
}
},deps:[AnotherstockService,'IS_DEV']},AnotherstockService,{provide:'IS_DEV',usevalue:true}]
在上方例子中,我们增加了值声明方式{provide:'IS_DEV',value:true}
,同时在工厂函数的deps中使用名为 ‘IS_DEV’ 的token,并赋值给匿名函数中的第2个参数isdev
usevalue还可以传入对象
providers: [
{provide:StockService,useFactory:(logger:AnotherstockService,isdev)=>{
let dev = Math.random() > 0.5;
console.log(isdev);
if(isdev.isDev){
return new StockService(logger);
}else{
return new Stock2Service(logger);
}
},deps:[AnotherstockService,'IS_DEV']},
AnotherstockService,
{provide:'IS_DEV',useValue:{isDev:false}}
]
Tips:useFactory创建的对象是个单例对象,也就是说,当我们先在stock.component中注入StockService,而后就算在stock2.component中也注入了StockService,工厂方法都只实行一次,即在stock.component和stock2.component中的StockService是一样的