* Creates a new injector, which contains providers collected from dependencies (NgModules) of * defer-loaded components. This function detects different types of parent injectors and creates * a new injector based on that.
( parentInjector: Injector, tDetails: TDeferBlockDetails, providers: Provider[], )
| 103 | * a new injector based on that. |
| 104 | */ |
| 105 | function createDeferBlockInjector( |
| 106 | parentInjector: Injector, |
| 107 | tDetails: TDeferBlockDetails, |
| 108 | providers: Provider[], |
| 109 | ) { |
| 110 | // Check if the parent injector is an instance of a `ChainedInjector`. |
| 111 | // |
| 112 | // In this case, we retain the shape of the injector and use a newly created |
| 113 | // `EnvironmentInjector` as a parent in the `ChainedInjector`. That is needed to |
| 114 | // make sure that the primary injector gets consulted first (since it's typically |
| 115 | // a NodeInjector) and `EnvironmentInjector` tree is consulted after that. |
| 116 | if (parentInjector instanceof ChainedInjector) { |
| 117 | const origInjector = parentInjector.injector; |
| 118 | // Guaranteed to be an environment injector |
| 119 | const parentEnvInjector = parentInjector.parentInjector; |
| 120 | |
| 121 | const envInjector = getOrCreateEnvironmentInjector(parentEnvInjector, tDetails, providers); |
| 122 | return new ChainedInjector(origInjector, envInjector); |
| 123 | } |
| 124 | |
| 125 | const parentEnvInjector = parentInjector.get(EnvironmentInjector); |
| 126 | |
| 127 | // If the `parentInjector` is *not* an `EnvironmentInjector` - we need to create |
| 128 | // a new `ChainedInjector` with the following setup: |
| 129 | // |
| 130 | // - the provided `parentInjector` becomes a primary injector |
| 131 | // - an existing (real) `EnvironmentInjector` becomes a parent injector for |
| 132 | // a newly-created one, which contains extra providers |
| 133 | // |
| 134 | // So the final order in which injectors would be consulted in this case would look like this: |
| 135 | // |
| 136 | // 1. Provided `parentInjector` |
| 137 | // 2. Newly-created `EnvironmentInjector` with extra providers |
| 138 | // 3. `EnvironmentInjector` from the `parentInjector` |
| 139 | if (parentEnvInjector !== parentInjector) { |
| 140 | const envInjector = getOrCreateEnvironmentInjector(parentEnvInjector, tDetails, providers); |
| 141 | return new ChainedInjector(parentInjector, envInjector); |
| 142 | } |
| 143 | |
| 144 | // The `parentInjector` is an instance of an `EnvironmentInjector`. |
| 145 | // No need for special handling, we can use `parentInjector` as a |
| 146 | // parent injector directly. |
| 147 | return getOrCreateEnvironmentInjector(parentInjector, tDetails, providers); |
| 148 | } |
| 149 | |
| 150 | /** Rendering Helpers */ |
| 151 |
no test coverage detected
searching dependent graphs…