0

众所周知,我们对提供商有不同的策略:useClass, useExisting, useFactory, useValue. 但是如果我想添加自己的策略怎么办?就像是:

providers: [ { MyService: MyService, useAsyncFactory: MyAsyncFactory} ]

扩展 ReflectiveInjector并使 Angular 使用您的扩展变体的最佳方法是什么?我找到了定义它的地方,但仍在寻找一种方法来覆盖现有的 Angular DI 机制。


PS:请不要问我为什么需要它,为什么不使用现有的策略。我正在研究 Angular DI,答案将帮助我更好地理解它。

4

1 回答 1

3

在引擎盖下,Angular 不ReflectiveInjector用于检索组件提供程序,因此即使您设法扩展 ReflectiveInjector,它也不会对组件提供程序产生任何影响。你可以在这里看到它:

 function resolveDep(...) {
       ...
        default:
          const providerDef =
              (allowPrivateServices ? elDef.element !.allProviders :
                                      elDef.element !.publicProviders) ![tokenKey];
          if (providerDef) {
            const providerData = asProviderData(view, providerDef.index);
                                 ^^^^^^^^^^^^^^^
            if (providerData.instance === NOT_CREATED) {
              providerData.instance = _createProviderInstance(view, providerDef);
            }
            return providerData.instance;
          }

当组件请求依赖时调用该方法,例如ViewContainerRef

class MyComponent {
   constructor(vc: ViewContainerRef)

而这一行:

const providerData = asProviderData(view, providerDef.index);

表明依赖关系是从视图节点检索的,而不是反射注入器。所以当你这样做时:

constructor(i: Injector) {
   console.log(i instanceOf ReflectiveInjector); // false
}

你会发现它不是真的。它只是一个封装resolveDep视图和相关视图节点的函数。

反射注入器仍然用于主机视图注入器。这是动态实例化组件时传递的注入器:

componentFactory.create(hostViewInjector)

以下是相关代码:

const value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);

如果您无法在组件或主机视图注入器上解决依赖关系,还会咨询模块注入器。
以下是相关代码:

return startView.root.ngModule.injector.get(depDef.token, notFoundValue);
于 2017-07-19T09:51:52.090 回答