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 8943870
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
15 changes: 15 additions & 0 deletions packages/common/interfaces/modules/provider.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,31 @@ export interface ClassProvider {
provide: any;
useClass: Type<any>;
scope?: Scope;
/**
* 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 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 {
provide: any;
useFactory: (...args: any[]) => any;
inject?: Array<Type<any> | string | any>;
scope?: Scope;
/**
* 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;
}
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
35 changes: 32 additions & 3 deletions 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 @@ -244,7 +249,7 @@ export class Module {
provider: CustomClass,
collection: Map<string, InstanceWrapper>,
) {
const { name, useClass, scope } = provider;
const { name, useClass, scope, multi } = provider;
collection.set(
name,
new InstanceWrapper({
Expand All @@ -253,6 +258,7 @@ export class Module {
instance: null,
isResolved: false,
scope,
multi,
host: this,
}),
);
Expand All @@ -262,7 +268,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 +299,7 @@ export class Module {
isResolved: true,
async: value instanceof Promise,
host: this,
multi,
}),
);
}
Expand All @@ -280,7 +308,7 @@ export class Module {
provider: CustomFactory,
collection: Map<string, InstanceWrapper>,
) {
const { name, useFactory: factory, inject, scope } = provider;
const { name, useFactory: factory, inject, scope, multi } = provider;
collection.set(
name,
new InstanceWrapper({
Expand All @@ -290,6 +318,7 @@ export class Module {
isResolved: false,
inject: inject || [],
scope,
multi,
host: this,
}),
);
Expand Down

0 comments on commit 8943870

Please sign in to comment.