diff --git a/modules/@angular/compiler/src/metadata_resolver.ts b/modules/@angular/compiler/src/metadata_resolver.ts index 276e3a0c78..bde95f4870 100644 --- a/modules/@angular/compiler/src/metadata_resolver.ts +++ b/modules/@angular/compiler/src/metadata_resolver.ts @@ -210,18 +210,6 @@ export class CompileMetadataResolver { const entryComponents: cpl.CompileTypeMetadata[] = []; const schemas: SchemaMetadata[] = []; - if (meta.providers) { - providers.push(...this.getProvidersMetadata(meta.providers, entryComponents)); - } - if (meta.entryComponents) { - entryComponents.push( - ...flattenArray(meta.entryComponents) - .map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type)))); - } - if (meta.schemas) { - schemas.push(...flattenArray(meta.schemas)); - } - if (meta.imports) { flattenArray(meta.imports).forEach((importedType) => { let importedModuleType: Type; @@ -295,6 +283,20 @@ export class CompileMetadataResolver { }); } + // The providers of the module have to go last + // so that they overwrite any other provider we already added. + if (meta.providers) { + providers.push(...this.getProvidersMetadata(meta.providers, entryComponents)); + } + if (meta.entryComponents) { + entryComponents.push( + ...flattenArray(meta.entryComponents) + .map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type)))); + } + if (meta.schemas) { + schemas.push(...flattenArray(meta.schemas)); + } + transitiveModule.entryComponents.push(...entryComponents); transitiveModule.providers.push(...providers); diff --git a/modules/@angular/core/test/linker/ng_module_integration_spec.ts b/modules/@angular/core/test/linker/ng_module_integration_spec.ts index 428fba6933..986129fcb7 100644 --- a/modules/@angular/core/test/linker/ng_module_integration_spec.ts +++ b/modules/@angular/core/test/linker/ng_module_integration_spec.ts @@ -960,6 +960,24 @@ function declareTests({useJit}: {useJit: boolean}) { expect(injector.get('token1')).toBe('direct'); }); + it('should overwrite the providers of imported ModuleWithProviders', () => { + @NgModule() + class ImportedModule { + } + + @NgModule({ + providers: [{provide: 'token1', useValue: 'direct'}], + imports: [ + {ngModule: ImportedModule, providers: [{provide: 'token1', useValue: 'imported'}]} + ] + }) + class SomeModule { + } + + const injector = createModule(SomeModule).injector; + expect(injector.get('token1')).toBe('direct'); + }); + it('should overwrite the providers of imported modules on the second import level', () => { @NgModule({providers: [{provide: 'token1', useValue: 'imported'}]}) class ImportedModuleLevel2 {