Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can factory provider have optional dependencies?

For example:

@NgModule ({
  providers: [ 
    { provide: MyService, 
      useFactory: (optionalDep) => new MyService(optionalDep)
      deps: [SOME_DEP]
    }
})
class MyModule {}

Can useFactory have optional dependencies?

like image 624
Krzysztof Bogdan Avatar asked Sep 01 '16 18:09

Krzysztof Bogdan


People also ask

What is an optional dependency?

Optional dependencies are used when it's not possible (for whatever reason) to split a project into sub-modules. The idea is that some of the dependencies are only used for certain features in the project and will not be needed if that feature isn't used.

What is true about the useClass provider option?

Class Provider: useClassThe useClass expects us to provide a type. The Injector creates a new instance from the type and injects it. It is similar to calling the new operator and returning instance. If the type requires any constructor parameters, the injector will resolve that also.

Which provider is used for dynamic Dependency Injection?

Factory providers: useFactory link The useFactory provider key lets you create a dependency object by calling a factory function, as in the following example. The injector provides the dependency value by invoking a factory function, that you provide as the value of the useFactory key.

What is optional dependency in Angular?

Angular has an @Optional decorator, which when applied to a constructor argument instructs the Angular injector to inject null if the dependency is not found.


2 Answers

According to official doc, you can do the following:

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');

See https://angular.io/api/core/FactoryProvider#example for more

like image 128
maxime1992 Avatar answered Oct 01 '22 03:10

maxime1992


I have found such a workaround:

class OptionalDepHolder {
  constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}

@NgModule ({
  providers: [ 
    { provide: MyService, 
      useFactory: (holder) => new MyService(holder.optionalDep)
      deps: [OptionalDepHolder]
    }
})
class MyModule {}
like image 25
Krzysztof Bogdan Avatar answered Oct 01 '22 03:10

Krzysztof Bogdan