You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 10生产构建手动实例化带DI类报错求助

Fixing Angular 10 Production Build DI Instantiation Issues

Let's tackle this Angular production build issue head-on— I've dealt with similar problems when working with manual DI instantiation, so I know exactly what's going wrong here.

What's Causing the Problem?

Your development environment works because it uses JIT compilation, which preserves the runtime reflection metadata that ReflectiveInjector relies on. But when you build with --prod (which enables AOT compilation and aggressive code optimization):

  • Angular strips away reflection metadata to reduce bundle size
  • Code compression obfuscates class names and parameter types
  • The deprecated ReflectiveInjector can no longer resolve constructor parameters, hence the Cannot resolve all parameters error

Additionally, using Injector.get() directly caches instances at the parent injector level, which defeats your goal of creating fresh instances on every call.

The Solution: Use Injector.create() (AOT-Compatible)

Angular 9+ introduced Injector.create(), the official replacement for ReflectiveInjector. It creates lightweight child injectors that avoid reflection, work with AOT, and let you generate fresh instances every time.

Step 1: Update Your Instantiation Method

Replace your instantiateWithDi function with this AOT-friendly version:

import { Injector, Type } from '@angular/core';

// ...

public instantiateWithDi(parentInjector: Injector, myClass: Type<any>): any {
  // Create a fresh child injector with your target class as a provider
  const childInjector = Injector.create({
    providers: [{ provide: myClass, useClass: myClass }],
    parent: parentInjector // Inherit dependencies from the parent injector
  });

  // Get a new instance from the child injector (no cross-instance caching)
  return childInjector.get(myClass);
}

Step 2: Validate Your @Injectable() Setup

Ensure your plugin classes have a properly configured @Injectable() decorator. Using providedIn: 'root' is the safest way to guarantee Angular generates the necessary AOT factory code:

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class YourPluginClass {
  constructor(private dependencyService: SomeRequiredService) { }
  // ... your plugin logic
}

If you need to register the class in a specific module's providers array instead, that's fine—just make sure it's registered before instantiation.

Step 3: Confirm Production Build Settings

Double-check your angular.json to ensure AOT is enabled (it's default for Angular 10 production builds):

"configurations": {
  "production": {
    "aot": true,
    "optimization": true,
    // ... other production settings
  }
}

Also, keep emitDecoratorMetadata: true in your tsconfig.json (it helps with DI resolution even for AOT):

"compilerOptions": {
  "emitDecoratorMetadata": true,
  // ... other TypeScript options
}

Why This Works

  • Each call to Injector.create() creates a new child injector, which maintains its own instance cache. This means you get a fresh instance of your class every time you call instantiateWithDi.
  • AOT compilation generates static factory code for @Injectable() classes during the build, so parameter resolution works even after code compression (no runtime reflection required).

Troubleshooting Tips

  • If you're using non-class dependencies, explicitly annotate them with @Inject() and use injection tokens.
  • Avoid anonymous classes or dynamically generated types—these break AOT compilation.
  • Test locally with ng build --prod to replicate the issue and validate your fix before deploying.

内容的提问来源于stack exchange,提问作者mesx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 08:42:40