diff --git a/goldens/circular-deps/packages.json b/goldens/circular-deps/packages.json index 3e9bf12faa..18f105b46f 100644 --- a/goldens/circular-deps/packages.json +++ b/goldens/circular-deps/packages.json @@ -176,6 +176,57 @@ "packages/core/src/change_detection/differs/default_keyvalue_differ.ts", "packages/core/src/change_detection/differs/keyvalue_differs.ts" ], + [ + "packages/core/src/di.ts", + "packages/core/src/di/index.ts", + "packages/core/src/di/injectable.ts", + "packages/core/src/di/jit/injectable.ts", + "packages/core/src/di/jit/environment.ts", + "packages/core/src/di/injector_compatibility.ts", + "packages/core/src/di/injector.ts", + "packages/core/src/di/metadata.ts", + "packages/core/src/render3/instructions/di.ts" + ], + [ + "packages/core/src/di.ts", + "packages/core/src/di/index.ts", + "packages/core/src/di/injectable.ts", + "packages/core/src/di/jit/injectable.ts", + "packages/core/src/di/jit/environment.ts", + "packages/core/src/di/injector_compatibility.ts", + "packages/core/src/di/metadata.ts", + "packages/core/src/render3/instructions/di.ts" + ], + [ + "packages/core/src/di.ts", + "packages/core/src/di/index.ts", + "packages/core/src/di/injectable.ts", + "packages/core/src/di/jit/injectable.ts", + "packages/core/src/di/jit/util.ts", + "packages/core/src/di/metadata.ts", + "packages/core/src/render3/instructions/di.ts" + ], + [ + "packages/core/src/di.ts", + "packages/core/src/di/index.ts", + "packages/core/src/di/metadata.ts", + "packages/core/src/render3/instructions/di.ts" + ], + [ + "packages/core/src/di.ts", + "packages/core/src/di/index.ts", + "packages/core/src/di/reflective_injector.ts", + "packages/core/src/di/metadata.ts", + "packages/core/src/render3/instructions/di.ts" + ], + [ + "packages/core/src/di.ts", + "packages/core/src/di/index.ts", + "packages/core/src/di/reflective_injector.ts", + "packages/core/src/di/reflective_provider.ts", + "packages/core/src/di/metadata.ts", + "packages/core/src/render3/instructions/di.ts" + ], [ "packages/core/src/di/injectable.ts", "packages/core/src/di/jit/injectable.ts" @@ -184,6 +235,16 @@ "packages/core/src/di/injector_compatibility.ts", "packages/core/src/di/injector.ts" ], + [ + "packages/core/src/di/injector_compatibility.ts", + "packages/core/src/di/injector.ts", + "packages/core/src/di/null_injector.ts" + ], + [ + "packages/core/src/di/injector_compatibility.ts", + "packages/core/src/di/injector.ts", + "packages/core/src/di/r3_injector.ts" + ], [ "packages/core/src/di/injector_token.ts", "packages/core/src/di/injector.ts" diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 668ec0c720..358a4316c3 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -25,6 +25,7 @@ export { SWITCH_COMPILE_INJECTABLE__POST_R3__ as ɵSWITCH_COMPILE_INJECTABLE__POST_R3__, } from './di/injectable'; export {INJECTOR_IMPL__POST_R3__ as ɵINJECTOR_IMPL__POST_R3__} from './di/injector'; +export {CREATE_ATTRIBUTE_DECORATOR__POST_R3__ as ɵCREATE_ATTRIBUTE_DECORATOR__POST_R3__} from './di/metadata'; export { NG_INJ_DEF as ɵNG_INJ_DEF, NG_PROV_DEF as ɵNG_PROV_DEF, diff --git a/packages/core/src/di/metadata.ts b/packages/core/src/di/metadata.ts index 521d6faf7b..658a39ef62 100644 --- a/packages/core/src/di/metadata.ts +++ b/packages/core/src/di/metadata.ts @@ -7,7 +7,7 @@ */ import {makeParamDecorator} from '../util/decorators'; - +import {ɵɵinjectAttribute} from '../render3/instructions/di'; /** @@ -274,11 +274,25 @@ export interface Attribute { attributeName: string; } +function CREATE_ATTRIBUTE_DECORATOR__PRE_R3__(): AttributeDecorator { + return makeParamDecorator( + 'Attribute', + (attributeName?: string) => ({attributeName})); +} + +export function CREATE_ATTRIBUTE_DECORATOR__POST_R3__(): AttributeDecorator { + return makeParamDecorator( + 'Attribute', + (attributeName?: string) => + ({attributeName, __NG_ELEMENT_ID__: () => ɵɵinjectAttribute(attributeName!)})); +} + +const CREATE_ATTRIBUTE_DECORATOR_IMPL = CREATE_ATTRIBUTE_DECORATOR__PRE_R3__; + /** * Attribute decorator and metadata. * * @Annotation * @publicApi - */ -export const Attribute: AttributeDecorator = - makeParamDecorator('Attribute', (attributeName?: string) => ({attributeName})); +*/ +export const Attribute: AttributeDecorator = CREATE_ATTRIBUTE_DECORATOR_IMPL(); diff --git a/packages/core/test/acceptance/di_spec.ts b/packages/core/test/acceptance/di_spec.ts index 820416d60e..70f59007a0 100644 --- a/packages/core/test/acceptance/di_spec.ts +++ b/packages/core/test/acceptance/di_spec.ts @@ -2771,6 +2771,38 @@ describe('di', () => { }); }); + describe('attribute tokens', () => { + it('should be able to provide an attribute token', () => { + const TOKEN = new InjectionToken('Some token'); + function factory(token: string): string { + return token + ' with factory'; + } + @Component({ + selector: 'my-comp', + template: '...', + providers: [{ + provide: TOKEN, + deps: [[new Attribute('token')]], + useFactory: factory, + }] + }) + class MyComp { + constructor(@Inject(TOKEN) readonly token: string) {} + } + + @Component({template: ``}) + class WrapperComp { + @ViewChild(MyComp) myComp!: MyComp; + } + + TestBed.configureTestingModule({declarations: [MyComp, WrapperComp]}); + + const fixture = TestBed.createComponent(WrapperComp); + fixture.detectChanges(); + expect(fixture.componentInstance.myComp.token).toBe('token with factory'); + }); + }); + it('should not cause cyclic dependency if same token is requested in deps with @SkipSelf', () => { @Component({ selector: 'my-comp',