![](/img/trans.png)
[英]Create new instance of class that has dependencies, not understanding factory provider
[英]Can factory provider have optional dependencies?
例如:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [SOME_DEP]
}
})
class MyModule {}
useFactory可以有可选的依赖吗?
根据官方文档,您可以执行以下操作:
const Location = new InjectionToken('location');
const Hash = new InjectionToken('hash');
const injector = Injector.create([{
provide: Hash,
useFactory: (location: string) => `Hash for: ${location}`,
// use a nested array to define metadata for dependencies.
deps: [[new Optional(), Location]]
}]);
expect(injector.get(Hash)).toEqual('Hash for: null');
有关更多信息,请参阅https://angular.io/api/core/FactoryProvider#example
我找到了这样一个解决方法:
class OptionalDepHolder {
constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (holder) => new MyService(holder.optionalDep)
deps: [OptionalDepHolder]
}
})
class MyModule {}
工厂接受一项功能。
typescript中的装饰器可以应用于:类声明,方法,访问器,属性或参数。
换句话说,目前你只能装饰一个类和类成员。
参数是指方法的参数,而不是函数。
因此,由于您无法在函数中修饰函数和更多参数,因此无法设置@Optional标记。
这是一种语言/规范限制,可能在将来发生变化。
需要注意的另一件事是,typescript支持的元数据功能和使用reflect-metadata的angular使用的元数据功能被设计用于类。 这当然是无稽之谈,类是函数......但这是一般的心理模型。
根据文档,deps数组接受提供程序令牌,这意味着您无法提示可选的依赖项。
在工厂中支持可选的依赖项是个好主意。 您应该通过功能请求打开GH问题!
确实可以为工厂提供者声明可选的依赖项。
export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
export const myOptionalServiceParameterDefault = 42;
然后,在提供者列表中,使用值提供者提供默认值
@NgModule({
providers: [
{
provide: MY_OPTIONAL_SERVICE_PARAMETER,
useValue: myOptionalServiceParameterDefault
},
{
provide: MyService,
useFactory: (optionalParam) => new MyService(optionalParam)
deps: [MY_OPTIONAL_SERVICE_PARAMETER]
}
})
export class Module {}
除非使用者稍后在提供者列表中覆盖该值, 否则该服务将使用所提供的参数的默认值(可能是undefined
)。
来自@angular/http
的HttpModule
使用此模式为其服务提供可选的依赖关系RequestOptions
。
所以我一直试图解决它。 检查一下:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [[new Optional(), new Inject(SOME_DEP)]]
}
})
class MyModule {}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.