I'm looking at the implementation of in-memory-web-api and there is the following code:
@Injectable()
export class InMemoryBackendService {
protected config: InMemoryBackendConfigArgs = new InMemoryBackendConfig();
^^^^^^
...
constructor(
@Inject(InMemoryBackendConfig) @Optional() config: InMemoryBackendConfigArgs
^^^^^^
) {
...
As I understand the pattern is the following:
- Defined class property and instantiate a dependency without using DI
- Optionally inject dependency
If a user provides modified dependency through DI, it will be injected and the default one instantiated without DI will be overridden. I suspect something similar maybe with RequestOptions in HTTP module.
Is this a common pattern?
EDIT:
It turns out that in-memory-web-api is not exactly the pattern I'm asking about. Suppose, I have a class A that uses instance of class B injectable with the token B. So they are both registered with the root injector:
providers: [A, B]
Now, if a user wants to customize B, he can register the customized version under the same token, thus effectively overrriding the original B:
providers: [{provide:B, useClass: extendedB}]`
This is how RequestOptions can be extended in http module.
The default value isn't just overridden. The most important part here is
Nothing would happen without it.
This pattern isn't specific to DI, it is a common recipe for default property values, similar to
_.defaults.I would say that
InMemoryBackendConfigdefault implementation is useless abstraction here. Sincethis.configis always merged withconfig, the former could be just a plain objectInMemoryBackendConfigandRequestOptionsuse complicated variations of this pattern. Yes, in most basic form this is how this can be done:This pattern is widely used by
constantservices in AngularJS for configuration objects, but havingBas a class instead of plain object allows to extend the original values instead of replacing them.