在runInContext中调用inject()触发NullInjectorError的原因咨询
在Angular中,当在runInContext里调用inject()时触发了NullInjectorError,但把Service设置为providedIn: 'root'或者在模块providers中声明就不会有问题,这是什么原因?
代码示例:
@Injectable() class Service {} @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [Service], }) export class AppComponent { name = 'Angular ' + VERSION.major; public constructor(service: Service, injector: EnvironmentInjector) { console.log(service); // OK console.log(inject(Service)); //OK setTimeout(() => { injector.runInContext(() => { console.log(inject(Service)); //KO }); }, 1000); } }
注入器层级与作用域限制:
组件providers数组中声明的Service属于组件级注入器的作用域,这个注入器绑定到组件实例的生命周期,仅组件自身及子组件能访问。而你注入的EnvironmentInjector是根/模块级的环境注入器,它无法访问组件级注入器内的服务。runInContext的执行上下文特性:EnvironmentInjector.runInContext()会在环境注入器的上下文里执行回调,这个上下文中只包含根或模块级注入器提供的服务。组件级的Service不在这个范围内,因此inject(Service)找不到依赖,抛出NullInjectorError。全局/模块级注册的作用:
当Service设置为providedIn: 'root'或在模块providers中声明时,服务会被注册到根注入器(或模块注入器,属于环境注入器的一部分),此时环境注入器能直接找到该服务,所以runInContext内的inject(Service)可以正常工作。构造函数内
inject正常的原因:
组件构造函数执行时,当前注入上下文是组件级注入器,因此能找到组件providers中的服务;而setTimeout里的runInContext切换到了环境注入器的上下文,自然无法访问组件级服务。
内容的提问来源于stack exchange,提问作者Matthieu Riegler

