Skip to content

Commit d5dedf4

Browse files
AleksanderBodurridylhunn
authored andcommitted
fix(core): get root and platform injector providers in special cases (angular#52365)
Previously, because the platform injector does not have a provider container, this API would fail. Now, we account for this case specifically by returning the found providers immediately, without trying to calculate their importpaths. Also previously, in the case where a boostrapped standalone component did not import any feature modules, the environment injector connected to that bootstrapped component would be the root injector configured by `bootstrapApplication`. This injector is configured through a `providers` array instead of an `imports` array, and also does not have a provider container. Similarly to the platform case, we account this for this by returning the found providers immediately if there is no provider container for our standalone component. PR Close angular#52365
1 parent 31b8870 commit d5dedf4

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

packages/core/src/render3/util/injector_discovery_utils.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ function getProviderImportsContainer(injector: Injector): Type<unknown>|null {
186186
return null;
187187
}
188188

189+
// In standalone applications, the root environment injector created by bootstrapApplication
190+
// may have no associated "instance".
191+
if (defTypeRef.instance === null) {
192+
return null;
193+
}
194+
189195
return defTypeRef.instance.constructor;
190196
}
191197

@@ -386,13 +392,29 @@ function walkProviderTreeToDiscoverImportPaths(
386392
* @returns an array of objects representing the providers of the given injector
387393
*/
388394
function getEnvironmentInjectorProviders(injector: EnvironmentInjector): ProviderRecord[] {
395+
const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
396+
397+
// platform injector has no provider imports container so can we skip trying to
398+
// find import paths
399+
if (isPlatformInjector(injector)) {
400+
return providerRecords;
401+
}
402+
389403
const providerImportsContainer = getProviderImportsContainer(injector);
390404
if (providerImportsContainer === null) {
405+
// There is a special case where the bootstrapped component does not
406+
// import any NgModules. In this case the environment injector connected to
407+
// that component is the root injector, which does not have a provider imports
408+
// container (and thus no concept of module import paths). Therefore we simply
409+
// return the provider records as is.
410+
if (isRootInjector(injector)) {
411+
return providerRecords;
412+
}
413+
391414
throwError('Could not determine where injector providers were configured.');
392415
}
393416

394417
const providerToPath = getProviderImportPaths(providerImportsContainer);
395-
const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
396418

397419
return providerRecords.map(providerRecord => {
398420
let importPath = providerToPath.get(providerRecord.provider) ?? [providerImportsContainer];
@@ -409,6 +431,14 @@ function getEnvironmentInjectorProviders(injector: EnvironmentInjector): Provide
409431
});
410432
}
411433

434+
function isPlatformInjector(injector: Injector) {
435+
return injector instanceof R3Injector && injector.scopes.has('platform');
436+
}
437+
438+
function isRootInjector(injector: Injector) {
439+
return injector instanceof R3Injector && injector.scopes.has('root');
440+
}
441+
412442
/**
413443
* Gets the providers configured on an injector.
414444
*

0 commit comments

Comments
 (0)