手动注入angular \ core服务,而不是通过构造函数

时间:2017-01-16 21:46:18

标签: angular dependency-injection

我正在尝试在Angular2应用程序中为popover类型控制器构建一个组件工厂。

我现在正在使用它,我将所有依赖项和我的组件传递给控制器​​,并通过componentFactoryResolver.resolveComponentFactory创建,它运行良好。

我希望调用者不必传递对依赖项的引用,但无法弄清楚如何管理它。我尝试过使用ReflectiveInjector.resolveAndCreate,但似乎无法管理。

如何设置它以便我可以访问ComponentFactoryResolver和ViewContainerRef而无需通过此服务的所有使用者导入和传递?请参阅下面的当前设置

呼叫者/演示

myPopover = new PopoverController(this.componentFactoryResolver, this.viewContainerRef, MyComponent);

PopoverController

constructor (private componentFactoryResolver: ComponentFactoryResolver, private viewContainerRef: ViewContainerRef, private myComponent: Component){
    let factory = this.componentFactoryResolver.resolveComponentFactory(<Type<Component>>myComponent);
    let res = this.viewContainerRef.createComponent(factory);
}

以上工作非常好,并且很好地构建了myComponent,我只是不必继续将refs传递给我的调用者的ComponentFactoryResolver和viewContainer,理论上他们不应该关心那些服务。

我尝试了类似下面的内容,但没有设法让它发挥作用

var injector = ReflectiveInjector.resolveAndCreate([ComponentFactoryResolver, ViewContainerRef]);

2 个答案:

答案 0 :(得分:2)

ReflectiveInjector会创建一个新的投影机实例,但不适用。注射器实例应该通过引用从另一个注射器传递。如果没有可用的注射器实例,则可以使用this technique获取根注入器(并且可能表明设计存在问题)。

ViewContainerRef不是正常@angular/core服务,它不会引用单例实例,而是引用特定于特定组件的实例。它不能用注射器检索。

当然,viewContainerRef需要通过引用传递。

It has injector property,这意味着不需要与viewContainerRef一起传递其他依赖项,可以就地检索它们:

const { injector } = viewContainerRef;
const componentFactoryResolver = injector.get(ComponentFactoryResolver);

答案 1 :(得分:0)

受上面接受的答案的启发,我找到了一种方法,使用Factory Providers比依赖ViewContainerRefComponentFactoryResolver类之间的关系更通用地完成此操作,尽管我的代码具有讽刺意味也需要它们:))

<强> my.service.provider.ts

import {MyService} from './my.service';
import {
  ComponentFactoryResolver,
  RendererFactory2,
  ViewContainerRef
} from '@angular/core';

const myServiceFactory = (rendererFactory, viewContainer, componentFactoryResolver) => {
  return new MyService(rendererFactory, viewContainer, componentFactoryResolver);
};

export const MyServiceProvider = {
  provide: MyService,
  useFactory: myServiceFactory,
  deps: [RendererFactory2, ViewContainerRef, ComponentFactoryResolver]
};

摘自需要服务的组件

@Component({
  ...
  providers: [MyServiceProvider],
  ...
})