feat(di): support map literals as providers

This commit is contained in:
Misko Hevery 2016-04-25 21:04:06 -07:00 committed by Martin Probst
parent b1a9e445b3
commit 46cd868827
5 changed files with 55 additions and 7 deletions

View File

@ -0,0 +1,20 @@
import './provider.dart' show Provider;
bool isProviderLiteral(dynamic obj) {
if (obj is Map) {
Map map = obj as Map;
return map.containsKey('provide');
} else {
return false;
}
}
Provider createProvider(dynamic obj) {
Map map = obj as Map;
return new Provider(map['provide'], useClass: map['useClass'],
useValue: map['useValue'],
useExisting: map['useExisting'],
useFactory: map['useFactory'],
deps: map['deps'],
multi: map['multi']);
}

View File

@ -0,0 +1,9 @@
import {Provider} from './provider';
export function isProviderLiteral(obj: any): boolean {
return obj && typeof obj == 'object' && obj.provide;
}
export function createProvider(obj: any): Provider {
return new Provider(obj.provide, obj);
}

View File

@ -391,7 +391,8 @@ export abstract class ReflectiveInjector implements Injector {
*
* See {@link ReflectiveInjector#fromResolvedProviders} for more info.
*/
static resolve(providers: Array<Type | Provider | any[]>): ResolvedReflectiveProvider[] {
static resolve(providers: Array<Type | Provider | {[k: string]: any} | any[]>):
ResolvedReflectiveProvider[] {
return resolveReflectiveProviders(providers);
}
@ -421,7 +422,7 @@ export abstract class ReflectiveInjector implements Injector {
* because it needs to resolve the passed-in providers first.
* See {@link Injector#resolve} and {@link Injector#fromResolvedProviders}.
*/
static resolveAndCreate(providers: Array<Type | Provider | any[]>,
static resolveAndCreate(providers: Array<Type | Provider | {[k: string]: any} | any[]>,
parent: Injector = null): ReflectiveInjector {
var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
@ -512,7 +513,8 @@ export abstract class ReflectiveInjector implements Injector {
* because it needs to resolve the passed-in providers first.
* See {@link Injector#resolve} and {@link Injector#createChildFromResolved}.
*/
resolveAndCreateChild(providers: Array<Type | Provider | any[]>): ReflectiveInjector {
resolveAndCreateChild(
providers: Array<Type | Provider | {[k: string]: any} | any[]>): ReflectiveInjector {
return unimplemented();
}

View File

@ -7,7 +7,7 @@ import {
isArray,
isType
} from 'angular2/src/facade/lang';
import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {MapWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {reflector} from 'angular2/src/core/reflection/reflection';
import {ReflectiveKey} from './reflective_key';
import {
@ -26,6 +26,7 @@ import {
} from './reflective_exceptions';
import {resolveForwardRef} from './forward_ref';
import {Provider, ProviderBuilder, provide} from './provider';
import {isProviderLiteral, createProvider} from './provider_util';
/**
* `Dependency` is used by the framework to extend DI.
@ -144,7 +145,7 @@ export function resolveReflectiveProvider(provider: Provider): ResolvedReflectiv
* Resolve a list of Providers.
*/
export function resolveReflectiveProviders(
providers: Array<Type | Provider | any[]>): ResolvedReflectiveProvider[] {
providers: Array<Type | Provider | {[k: string]: any} | any[]>): ResolvedReflectiveProvider[] {
var normalized = _normalizeProviders(providers, []);
var resolved = normalized.map(resolveReflectiveProvider);
return MapWrapper.values(
@ -188,8 +189,9 @@ export function mergeResolvedReflectiveProviders(
return normalizedProvidersMap;
}
function _normalizeProviders(providers: Array<Type | Provider | ProviderBuilder | any[]>,
res: Provider[]): Provider[] {
function _normalizeProviders(
providers: Array<Type | Provider | {[k: string]: any} | ProviderBuilder | any[]>,
res: Provider[]): Provider[] {
providers.forEach(b => {
if (b instanceof Type) {
res.push(provide(b, {useClass: b}));
@ -197,6 +199,9 @@ function _normalizeProviders(providers: Array<Type | Provider | ProviderBuilder
} else if (b instanceof Provider) {
res.push(b);
} else if (isProviderLiteral(b)) {
res.push(createProvider(b));
} else if (b instanceof Array) {
_normalizeProviders(b, res);

View File

@ -532,6 +532,18 @@ export function main() {
expect(provider.resolvedFactories.length).toEqual(2);
});
it("should support providers as hash", () => {
var provider = ReflectiveInjector.resolve([
{provide: Engine, useClass: BrokenEngine, multi: true},
{provide: Engine, useClass: TurboEngine, multi: true}
])[0];
expect(provider.key.token).toBe(Engine);
expect(provider.multiProvider).toEqual(true);
expect(provider.resolvedFactories.length).toEqual(2);
});
it("should support multi providers with only one provider", () => {
var provider = ReflectiveInjector.resolve(
[new Provider(Engine, {useClass: BrokenEngine, multi: true})])[0];