From 7a8513b64907b3e1aec7c20c8234679c4ebf9135 Mon Sep 17 00:00:00 2001
From: Mihail Goloborodov <Mihail.Goloborodov@nexign-systems.com>
Date: Mon, 23 Jan 2023 18:18:41 +0300
Subject: [PATCH 1/2] fix: uiView component injector

---
 src/directives/uiView.ts |  8 +++-----
 src/mergeInjector.ts     | 39 ---------------------------------------
 2 files changed, 3 insertions(+), 44 deletions(-)
 delete mode 100644 src/mergeInjector.ts

diff --git a/src/directives/uiView.ts b/src/directives/uiView.ts
index cac7a8e04..d33f9fce3 100755
--- a/src/directives/uiView.ts
+++ b/src/directives/uiView.ts
@@ -33,7 +33,6 @@ import {
   ViewContext,
 } from '@uirouter/core';
 import { Ng2ViewConfig } from '../statebuilders/views';
-import { MergeInjector } from '../mergeInjector';
 
 /** @hidden */
 let id = 0;
@@ -291,7 +290,8 @@ export class UIView implements OnInit, OnDestroy {
     const componentClass = config.viewDecl.component;
 
     // Create the component
-    const compFactoryResolver = componentInjector.get(ComponentFactoryResolver);
+    const moduleInjector = context.getResolvable(NATIVE_INJECTOR_TOKEN).data;
+    const compFactoryResolver = moduleInjector.get(ComponentFactoryResolver);
     const compFactory = compFactoryResolver.resolveComponentFactory(componentClass);
     this._componentRef = this._componentTarget.createComponent(compFactory, undefined, componentInjector);
 
@@ -322,10 +322,8 @@ export class UIView implements OnInit, OnDestroy {
     newProviders.push({ provide: UIView.PARENT_INJECT, useValue: parentInject });
 
     const parentComponentInjector = this.viewContainerRef.injector;
-    const moduleInjector = context.getResolvable(NATIVE_INJECTOR_TOKEN).data;
-    const mergedParentInjector = new MergeInjector(moduleInjector, parentComponentInjector);
 
-    return ReflectiveInjector.resolveAndCreate(newProviders, mergedParentInjector);
+    return Injector.create({ providers: newProviders, parent: parentComponentInjector });
   }
 
   /**
diff --git a/src/mergeInjector.ts b/src/mergeInjector.ts
deleted file mode 100644
index b82a45a9d..000000000
--- a/src/mergeInjector.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { Injector } from '@angular/core';
-
-/**
- * Merge two injectors
- *
- * This class implements the Injector ng2 interface but delegates
- * to the Injectors provided in the constructor.
- */
-export class MergeInjector implements Injector {
-  static NOT_FOUND = {};
-  private injectors: Injector[];
-  constructor(...injectors: Injector[]) {
-    if (injectors.length < 2) throw new Error('pass at least two injectors');
-    this.injectors = injectors;
-  }
-
-  /**
-   * Get the token from the first injector which contains it.
-   *
-   * Delegates to the first Injector.get().
-   * If not found, then delegates to the second Injector (and so forth).
-   * If no Injector contains the token, return the `notFoundValue`, or throw.
-   *
-   * @param token the DI token
-   * @param notFoundValue the value to return if none of the Injectors contains the token.
-   * @returns {any} the DI value
-   */
-  get(token: any, notFoundValue?: any): any {
-    for (let i = 0; i < this.injectors.length; i++) {
-      const val = this.injectors[i].get(token, MergeInjector.NOT_FOUND);
-      if (val !== MergeInjector.NOT_FOUND) return val;
-    }
-
-    if (arguments.length >= 2) return notFoundValue;
-
-    // This will throw the DI Injector error
-    this.injectors[0].get(token);
-  }
-}

From 930accf320db1fa48659b13ed2c18859650ab9f7 Mon Sep 17 00:00:00 2001
From: Mihail Goloborodov <Mihail.Goloborodov@nexign-systems.com>
Date: Fri, 10 Mar 2023 16:35:44 +0300
Subject: [PATCH 2/2] fix: remove deprecated NgModuleFactory, Compiler,
 ComponentFactoryResolver

---
 src/directives/uiView.ts         | 24 ++++++++++++--------
 src/lazyLoad/lazyLoadNgModule.ts | 39 +++++---------------------------
 2 files changed, 21 insertions(+), 42 deletions(-)

diff --git a/src/directives/uiView.ts b/src/directives/uiView.ts
index d33f9fce3..a9a54ebb3 100755
--- a/src/directives/uiView.ts
+++ b/src/directives/uiView.ts
@@ -1,14 +1,13 @@
 import {
   Component,
-  ComponentFactory,
-  ComponentFactoryResolver,
+  ComponentMirror,
   ComponentRef,
   Inject,
   Injector,
   Input,
   OnDestroy,
   OnInit,
-  ReflectiveInjector,
+  reflectComponentType,
   ViewChild,
   ViewContainerRef,
 } from '@angular/core';
@@ -57,7 +56,7 @@ interface InputMapping {
  *
  * @internal
  */
-const ng2ComponentInputs = (factory: ComponentFactory<any>): InputMapping[] => {
+const ng2ComponentInputs = (factory: ComponentMirror<any>): InputMapping[] => {
   return factory.inputs.map((input) => ({ prop: input.propName, token: input.templateName }));
 };
 
@@ -291,12 +290,19 @@ export class UIView implements OnInit, OnDestroy {
 
     // Create the component
     const moduleInjector = context.getResolvable(NATIVE_INJECTOR_TOKEN).data;
-    const compFactoryResolver = moduleInjector.get(ComponentFactoryResolver);
-    const compFactory = compFactoryResolver.resolveComponentFactory(componentClass);
-    this._componentRef = this._componentTarget.createComponent(compFactory, undefined, componentInjector);
+
+    this._componentRef = this._componentTarget.createComponent(componentClass, {
+      injector: componentInjector,
+      environmentInjector: moduleInjector
+    });
 
     // Wire resolves to @Input()s
-    this._applyInputBindings(compFactory, this._componentRef.instance, context, componentClass);
+    this._applyInputBindings(
+      reflectComponentType(componentClass),
+      this._componentRef.instance,
+      context,
+      componentClass
+    );
   }
 
   /**
@@ -332,7 +338,7 @@ export class UIView implements OnInit, OnDestroy {
    * Finds component inputs which match resolves (by name) and sets the input value
    * to the resolve data.
    */
-  private _applyInputBindings(factory: ComponentFactory<any>, component: any, context: ResolveContext, componentClass) {
+  private _applyInputBindings(factory: ComponentMirror<any>, component: any, context: ResolveContext, componentClass) {
     const bindings = this._uiViewData.config.viewDecl['bindings'] || {};
     const explicitBoundProps = Object.keys(bindings);
 
diff --git a/src/lazyLoad/lazyLoadNgModule.ts b/src/lazyLoad/lazyLoadNgModule.ts
index e4d362ac1..b25f7580d 100644
--- a/src/lazyLoad/lazyLoadNgModule.ts
+++ b/src/lazyLoad/lazyLoadNgModule.ts
@@ -1,11 +1,10 @@
-import { NgModuleRef, Injector, NgModuleFactory, Type, Compiler } from '@angular/core';
+import { NgModuleRef, Injector, Type, createNgModule } from '@angular/core';
 import {
   Transition,
   LazyLoadResult,
   UIRouter,
   Resolvable,
   NATIVE_INJECTOR_TOKEN,
-  isString,
   unnestR,
   inArray,
   StateObject,
@@ -72,42 +71,16 @@ export function loadNgModule(
 ): (transition: Transition, stateObject: StateDeclaration) => Promise<LazyLoadResult> {
   return (transition: Transition, stateObject: StateDeclaration) => {
     const ng2Injector = transition.injector().get(NATIVE_INJECTOR_TOKEN);
-
-    const createModule = (factory: NgModuleFactory<any>) => factory.create(ng2Injector);
-
+    const unwrapEsModuleDefault = x => (x && x.__esModule && x['default'] ? x['default'] : x);
     const applyModule = (moduleRef: NgModuleRef<any>) => applyNgModule(transition, moduleRef, ng2Injector, stateObject);
 
-    return loadModuleFactory(moduleToLoad, ng2Injector).then(createModule).then(applyModule);
+    return Promise.resolve(moduleToLoad())
+      .then(unwrapEsModuleDefault)
+      .then((ngModule: Type<any>) => createNgModule(ngModule, ng2Injector))
+      .then(applyModule);
   };
 }
 
-/**
- * Returns the module factory that can be used to instantiate a module
- *
- * For a Type<any> or Promise<Type<any>> this:
- * - Compiles the component type (if not running with AOT)
- * - Returns the NgModuleFactory resulting from compilation (or direct loading if using AOT) as a Promise
- *
- * @internal
- */
-export function loadModuleFactory(
-  moduleToLoad: ModuleTypeCallback,
-  ng2Injector: Injector
-): Promise<NgModuleFactory<any>> {
-  const compiler: Compiler = ng2Injector.get(Compiler);
-
-  const unwrapEsModuleDefault = (x) => (x && x.__esModule && x['default'] ? x['default'] : x);
-
-  return Promise.resolve(moduleToLoad())
-    .then(unwrapEsModuleDefault)
-    .then((t: NgModuleFactory<any> | Type<any>) => {
-      if (t instanceof NgModuleFactory) {
-        return t;
-      }
-      return compiler.compileModuleAsync(t);
-    });
-}
-
 /**
  * Apply the UI-Router Modules found in the lazy loaded module.
  *