Skip to content

Commit aaa3111

Browse files
sonukapoorAndrewKushnir
authored andcommitted
fix(core): support Attribute DI decorator in deps section of a token (#37085)
This commit fixes a bug when `Attribute` DI decorator is used in the `deps` section of a token that uses a factory function. The problem appeared because the `Attribute` DI decorator was not handled correctly while injecting factory function attributes. Closes #36479 PR Close #37085
1 parent 29fdbf2 commit aaa3111

File tree

4 files changed

+112
-4
lines changed

4 files changed

+112
-4
lines changed

goldens/circular-deps/packages.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,57 @@
180180
"packages/core/src/change_detection/differs/default_keyvalue_differ.ts",
181181
"packages/core/src/change_detection/differs/keyvalue_differs.ts"
182182
],
183+
[
184+
"packages/core/src/di.ts",
185+
"packages/core/src/di/index.ts",
186+
"packages/core/src/di/injectable.ts",
187+
"packages/core/src/di/jit/injectable.ts",
188+
"packages/core/src/di/jit/environment.ts",
189+
"packages/core/src/di/injector_compatibility.ts",
190+
"packages/core/src/di/injector.ts",
191+
"packages/core/src/di/metadata.ts",
192+
"packages/core/src/render3/instructions/di.ts"
193+
],
194+
[
195+
"packages/core/src/di.ts",
196+
"packages/core/src/di/index.ts",
197+
"packages/core/src/di/injectable.ts",
198+
"packages/core/src/di/jit/injectable.ts",
199+
"packages/core/src/di/jit/environment.ts",
200+
"packages/core/src/di/injector_compatibility.ts",
201+
"packages/core/src/di/metadata.ts",
202+
"packages/core/src/render3/instructions/di.ts"
203+
],
204+
[
205+
"packages/core/src/di.ts",
206+
"packages/core/src/di/index.ts",
207+
"packages/core/src/di/injectable.ts",
208+
"packages/core/src/di/jit/injectable.ts",
209+
"packages/core/src/di/jit/util.ts",
210+
"packages/core/src/di/metadata.ts",
211+
"packages/core/src/render3/instructions/di.ts"
212+
],
213+
[
214+
"packages/core/src/di.ts",
215+
"packages/core/src/di/index.ts",
216+
"packages/core/src/di/metadata.ts",
217+
"packages/core/src/render3/instructions/di.ts"
218+
],
219+
[
220+
"packages/core/src/di.ts",
221+
"packages/core/src/di/index.ts",
222+
"packages/core/src/di/reflective_injector.ts",
223+
"packages/core/src/di/metadata.ts",
224+
"packages/core/src/render3/instructions/di.ts"
225+
],
226+
[
227+
"packages/core/src/di.ts",
228+
"packages/core/src/di/index.ts",
229+
"packages/core/src/di/reflective_injector.ts",
230+
"packages/core/src/di/reflective_provider.ts",
231+
"packages/core/src/di/metadata.ts",
232+
"packages/core/src/render3/instructions/di.ts"
233+
],
183234
[
184235
"packages/core/src/di/injectable.ts",
185236
"packages/core/src/di/jit/injectable.ts"
@@ -188,6 +239,16 @@
188239
"packages/core/src/di/injector_compatibility.ts",
189240
"packages/core/src/di/injector.ts"
190241
],
242+
[
243+
"packages/core/src/di/injector_compatibility.ts",
244+
"packages/core/src/di/injector.ts",
245+
"packages/core/src/di/null_injector.ts"
246+
],
247+
[
248+
"packages/core/src/di/injector_compatibility.ts",
249+
"packages/core/src/di/injector.ts",
250+
"packages/core/src/di/r3_injector.ts"
251+
],
191252
[
192253
"packages/core/src/di/injector_token.ts",
193254
"packages/core/src/di/injector.ts"

packages/core/src/core_render3_private_export.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export {
2525
SWITCH_COMPILE_INJECTABLE__POST_R3__ as ɵSWITCH_COMPILE_INJECTABLE__POST_R3__,
2626
} from './di/injectable';
2727
export {INJECTOR_IMPL__POST_R3__ as ɵINJECTOR_IMPL__POST_R3__} from './di/injector';
28+
export {CREATE_ATTRIBUTE_DECORATOR__POST_R3__ as ɵCREATE_ATTRIBUTE_DECORATOR__POST_R3__} from './di/metadata';
2829
export {
2930
NG_INJ_DEF as ɵNG_INJ_DEF,
3031
NG_PROV_DEF as ɵNG_PROV_DEF,

packages/core/src/di/metadata.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {makeParamDecorator} from '../util/decorators';
10-
10+
import {ɵɵinjectAttribute} from '../render3/instructions/di';
1111

1212

1313
/**
@@ -274,11 +274,25 @@ export interface Attribute {
274274
attributeName: string;
275275
}
276276

277+
function CREATE_ATTRIBUTE_DECORATOR__PRE_R3__(): AttributeDecorator {
278+
return makeParamDecorator(
279+
'Attribute',
280+
(attributeName?: string) => ({attributeName}));
281+
}
282+
283+
export function CREATE_ATTRIBUTE_DECORATOR__POST_R3__(): AttributeDecorator {
284+
return makeParamDecorator(
285+
'Attribute',
286+
(attributeName?: string) =>
287+
({attributeName, __NG_ELEMENT_ID__: () => ɵɵinjectAttribute(attributeName!)}));
288+
}
289+
290+
const CREATE_ATTRIBUTE_DECORATOR_IMPL = CREATE_ATTRIBUTE_DECORATOR__PRE_R3__;
291+
277292
/**
278293
* Attribute decorator and metadata.
279294
*
280295
* @Annotation
281296
* @publicApi
282-
*/
283-
export const Attribute: AttributeDecorator =
284-
makeParamDecorator('Attribute', (attributeName?: string) => ({attributeName}));
297+
*/
298+
export const Attribute: AttributeDecorator = CREATE_ATTRIBUTE_DECORATOR_IMPL();

packages/core/test/acceptance/di_spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,6 +2771,38 @@ describe('di', () => {
27712771
});
27722772
});
27732773

2774+
describe('attribute tokens', () => {
2775+
it('should be able to provide an attribute token', () => {
2776+
const TOKEN = new InjectionToken<string>('Some token');
2777+
function factory(token: string): string {
2778+
return token + ' with factory';
2779+
}
2780+
@Component({
2781+
selector: 'my-comp',
2782+
template: '...',
2783+
providers: [{
2784+
provide: TOKEN,
2785+
deps: [[new Attribute('token')]],
2786+
useFactory: factory,
2787+
}]
2788+
})
2789+
class MyComp {
2790+
constructor(@Inject(TOKEN) readonly token: string) {}
2791+
}
2792+
2793+
@Component({template: `<my-comp token='token'></my-comp>`})
2794+
class WrapperComp {
2795+
@ViewChild(MyComp) myComp!: MyComp;
2796+
}
2797+
2798+
TestBed.configureTestingModule({declarations: [MyComp, WrapperComp]});
2799+
2800+
const fixture = TestBed.createComponent(WrapperComp);
2801+
fixture.detectChanges();
2802+
expect(fixture.componentInstance.myComp.token).toBe('token with factory');
2803+
});
2804+
});
2805+
27742806
it('should not cause cyclic dependency if same token is requested in deps with @SkipSelf', () => {
27752807
@Component({
27762808
selector: 'my-comp',

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy