( lView: LView, tView: TView, index: number, tNode: TDirectiveHostNode, flags?: InternalInjectFlags, )
| 733 | * instantiates the `injectable` and caches the value. |
| 734 | */ |
| 735 | export function getNodeInjectable( |
| 736 | lView: LView, |
| 737 | tView: TView, |
| 738 | index: number, |
| 739 | tNode: TDirectiveHostNode, |
| 740 | flags?: InternalInjectFlags, |
| 741 | ): any { |
| 742 | let value = lView[index]; |
| 743 | const tData = tView.data; |
| 744 | if (value instanceof NodeInjectorFactory) { |
| 745 | const factory: NodeInjectorFactory = value; |
| 746 | ngDevMode && injectionPath.push(factory.name ?? 'unknown'); |
| 747 | if (factory.resolving) { |
| 748 | let token = ''; |
| 749 | if (ngDevMode) { |
| 750 | token = stringifyForError(tData[index]); |
| 751 | throw cyclicDependencyErrorWithDetails(token, injectionPath); |
| 752 | } else { |
| 753 | throw cyclicDependencyError(token); |
| 754 | } |
| 755 | } |
| 756 | const previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders); |
| 757 | factory.resolving = true; |
| 758 | |
| 759 | // tData indexes mirror the concrete instances in its corresponding LView. |
| 760 | // lView[index] here is either the injectable instance itself or a factory, |
| 761 | // therefore tData[index] is the constructor of that injectable or a |
| 762 | // definition object that contains the constructor in a `.type` field. |
| 763 | const token = |
| 764 | (tData[index] as DirectiveDef<unknown> | ComponentDef<unknown>).type || tData[index]; |
| 765 | |
| 766 | let prevInjectContext: InjectorProfilerContext | undefined; |
| 767 | if (ngDevMode) { |
| 768 | const injector = new NodeInjector(tNode, lView); |
| 769 | prevInjectContext = setInjectorProfilerContext({injector, token}); |
| 770 | } |
| 771 | |
| 772 | const previousInjectImplementation = factory.injectImpl |
| 773 | ? setInjectImplementation(factory.injectImpl) |
| 774 | : null; |
| 775 | const success = enterDI(lView, tNode, InternalInjectFlags.Default); |
| 776 | ngDevMode && |
| 777 | assertEqual( |
| 778 | success, |
| 779 | true, |
| 780 | "Because flags do not contain `SkipSelf' we expect this to always succeed.", |
| 781 | ); |
| 782 | try { |
| 783 | ngDevMode && emitInjectorToCreateInstanceEvent(token); |
| 784 | |
| 785 | value = lView[index] = factory.factory(undefined, flags, tData, lView, tNode); |
| 786 | |
| 787 | ngDevMode && emitInstanceCreatedByInjectorEvent(value); |
| 788 | |
| 789 | // This code path is hit for both directives and providers. |
| 790 | // For perf reasons, we want to avoid searching for hooks on providers. |
| 791 | // It does no harm to try (the hooks just won't exist), but the extra |
| 792 | // checks are unnecessary and this is a hot path. So we check to see |
no test coverage detected
searching dependent graphs…