繁体   English   中英

工厂提供商可以选择依赖吗?

[英]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/httpHttpModule使用此模式为其服务提供可选的依赖关系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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM