Skip to content

Commit

Permalink
feature(core): Add multi option for custom useValue-providers
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunnerLivio committed Feb 2, 2019
1 parent ad6dd43 commit f1b3abc
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
5 changes: 5 additions & 0 deletions packages/common/interfaces/modules/provider.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export interface ClassProvider {
export interface ValueProvider {
provide: any;
useValue: any;
/**
* If true, then injector returns an array of instances. This is useful to allow multiple
* providers spread across many files to provide configuration information to a common token.
*/
multi?: boolean | undefined;
}

export interface FactoryProvider {
Expand Down
1 change: 1 addition & 0 deletions packages/core/injector/instance-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class InstanceWrapper<T = any> {
public readonly inject?: (string | symbol | Function | Type<any>)[];
public readonly async?: boolean;
public readonly host?: Module;
public readonly multi?: boolean | undefined;
public readonly scope?: Scope = Scope.DEFAULT;
public forwardRef?: boolean;

Expand Down
29 changes: 28 additions & 1 deletion packages/core/injector/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ import { ModuleRef } from './module-ref';
export interface CustomProvider {
provide: any;
name: string;
/**
* If true, then injector returns an array of instances. This is useful to allow multiple
* providers spread across many files to provide configuration information to a common token.
*/
multi?: boolean;
}
export type OpaqueToken = string | symbol | Type<any>;
export type CustomClass = CustomProvider & {
Expand Down Expand Up @@ -262,7 +267,28 @@ export class Module {
provider: CustomValue,
collection: Map<string, InstanceWrapper>,
) {
const { name, useValue: value } = provider;
const { name, multi } = provider;
let value = provider.useValue;

if (multi === true) {
// If the provider indicates that it's a multi-provider, process it specially.
// First check whether it's been defined already.
const multiItem = collection.get(name);
if (multiItem) {
// It has. Throw a nice error if
if (multiItem.multi === undefined) {
throw new Error(`Mixed multi-provider for ${name}.`);
} else {
// A provider already exists. Append new value
value = [...multiItem.instance, value];
}
} else {
// First multi provider
value = [value];
}

}

collection.set(
name,
new InstanceWrapper({
Expand All @@ -272,6 +298,7 @@ export class Module {
isResolved: true,
async: value instanceof Promise,
host: this,
multi,
}),
);
}
Expand Down

0 comments on commit f1b3abc

Please sign in to comment.