StaticInjector
должен заменить ReflectiveInjector
, который не требует Reflect
API. getAnnotations
- хак низкого уровня и, скорее всего, не будет работать с StaticInjector
в его текущем состоянии. Также, getAnnotations
несовместимо с AOT по дизайну.
Желательно создать инжектор для модуля так, как это должно быть сделано фреймворком, то есть модуль должен быть загружен. Поскольку нет компонента для начальной загрузки, необходимо указать ngDoBootstrap
hook.
По умолчанию процесс начальной загрузки является асинхронным. Если это не проблема, обещание инициализации можно связать для получения экземпляра модуля.
Пример :
@NgModule({
imports: [BrowserModule, HttpClientModule]
})
export class MyHttpModule {
static httpClient?: HttpClient;
httpClient?: HttpClient;
constructor(private _injector: Injector) {}
ngDoBootstrap() {
MyHttpModule.httpClient = this.httpClient = this._injector.get(HttpClient);
}
}
platformBrowserDynamic().bootstrapModule(MyHttpModule)
.then((myHttpModule: NgModuleRef<MyHttpModule>) => {
// HttpClient instance is available here
const httpClient = myHttpModule.instance.httpClient;
httpClient.get('/foo', { responseType: 'text'}).subscribe();
})
.catch(err => console.error(err));
Этот подход совместим как с JIT, так и с AOT (что хорошо для использования HttpClient
отдельно от Angular, потому что это значительно уменьшает площадь) из коробки.
В противном случае можно выполнить пользовательскую синхронную процедуру начальной загрузки. Это возможно, потому что HttpClient
не требует асинхронной инициализации.
An пример :
@NgModule({
imports: [BrowserModule, HttpClientModule]
})
export class MyHttpModule {
static httpClient?: HttpClient;
constructor(public _injector: Injector) {
MyHttpModule.httpClient = this._injector.get(HttpClient);
}
ngDoBootstrap() {}
}
const platform = platformBrowserDynamic();
const compiler = platform.injector.get(CompilerFactory).createCompiler();
const moduleFactory = compiler.compileModuleSync(MyHttpModule);
platform.bootstrapModuleFactory(moduleFactory)
.catch(err => console.error(err));
const httpClient = MyHttpModule.httpClient;
httpClient.get('/foo').subscribe();
Это будет работать в JIT, но AOT не может быть эффективно обработан Angular CLI в приведенном выше коде. В коде используется компилятор, который не нужен в режиме компиляции AOT (в этом его цель). Чтобы использовать AOT, он должен быть скомпилирован с помощью ngc
компилятора, и должна быть создана отдельная точка входа, которая использует фабрики модулей. Процедура начальной загрузки становится еще проще, потому что она не включает компилятор, что-то вроде:
...
import { platformBrowser } from '@angular/platform-browser-dynamic';
import { AppModuleNgFactory } from '<path to aot>/src/app/my-http-module.ngfactory';
const platform = platformBrowser();
platform.bootstrapModuleFactory(AppModuleNgFactory)
.catch(err => console.error(err));
const httpClient = MyHttpModule.httpClient;
httpClient.get('/foo').subscribe();