Skip to content

Commit 7853332

Browse files
AleksanderBodurridylhunn
authored andcommitted
fix(core): get root and platform injector providers in special cases (#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 #52365
1 parent 54ea3b6 commit 7853332

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
@@ -151,6 +151,12 @@ function getProviderImportsContainer(injector: Injector): Type<unknown>|null {
151151
return null;
152152
}
153153

154+
// In standalone applications, the root environment injector created by bootstrapApplication
155+
// may have no associated "instance".
156+
if (defTypeRef.instance === null) {
157+
return null;
158+
}
159+
154160
return defTypeRef.instance.constructor;
155161
}
156162

@@ -351,13 +357,29 @@ function walkProviderTreeToDiscoverImportPaths(
351357
* @returns an array of objects representing the providers of the given injector
352358
*/
353359
function getEnvironmentInjectorProviders(injector: EnvironmentInjector): ProviderRecord[] {
360+
const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
361+
362+
// platform injector has no provider imports container so can we skip trying to
363+
// find import paths
364+
if (isPlatformInjector(injector)) {
365+
return providerRecords;
366+
}
367+
354368
const providerImportsContainer = getProviderImportsContainer(injector);
355369
if (providerImportsContainer === null) {
370+
// There is a special case where the bootstrapped component does not
371+
// import any NgModules. In this case the environment injector connected to
372+
// that component is the root injector, which does not have a provider imports
373+
// container (and thus no concept of module import paths). Therefore we simply
374+
// return the provider records as is.
375+
if (isRootInjector(injector)) {
376+
return providerRecords;
377+
}
378+
356379
throwError('Could not determine where injector providers were configured.');
357380
}
358381

359382
const providerToPath = getProviderImportPaths(providerImportsContainer);
360-
const providerRecords = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
361383

362384
return providerRecords.map(providerRecord => {
363385
let importPath = providerToPath.get(providerRecord.provider) ?? [providerImportsContainer];
@@ -374,6 +396,14 @@ function getEnvironmentInjectorProviders(injector: EnvironmentInjector): Provide
374396
});
375397
}
376398

399+
function isPlatformInjector(injector: Injector) {
400+
return injector instanceof R3Injector && injector.scopes.has('platform');
401+
}
402+
403+
function isRootInjector(injector: Injector) {
404+
return injector instanceof R3Injector && injector.scopes.has('root');
405+
}
406+
377407
/**
378408
* Gets the providers configured on an injector.
379409
*

0 commit comments

Comments
 (0)