Dependency injection 如何在Angular2中正确使用依赖注入?

Dependency injection 如何在Angular2中正确使用依赖注入?,dependency-injection,angular,Dependency Injection,Angular,我在解决与DI的问题方面取得了好坏参半的成功。我读了一些教程,获得了jist,但在使用我的定制服务制作了一些嵌套的DI之后,事情开始崩溃 有人能解释一下什么时候使用useFactory而不是useClass吗?我看过ng2文档和示例,但我无法将它们映射到我的问题。目前,我的引导程序如下所示: bootstrap( 应用程序, [ 表格供应商, 路由器供应商, HTTP_提供商, 提供(LocationStrategy,{useClass:PathLocationStrategy}), 提供(Re

我在解决与DI的问题方面取得了好坏参半的成功。我读了一些教程,获得了jist,但在使用我的定制服务制作了一些嵌套的DI之后,事情开始崩溃

有人能解释一下什么时候使用useFactory而不是useClass吗?我看过ng2文档和示例,但我无法将它们映射到我的问题。目前,我的引导程序如下所示:

bootstrap(
应用程序,
[
表格供应商,
路由器供应商,
HTTP_提供商,
提供(LocationStrategy,{useClass:PathLocationStrategy}),
提供(RequestOptions,{useClass:DefaultRequestOptions}),
提供(MsgService,{useClass:MsgService}),
提供(HttpAdvanced,{useFactory:(MsgService,HTTP_PROVIDERS)=>新的HttpAdvanced(MsgService,HTTP_PROVIDERS),deps:[MsgService,HTTP_PROVIDERS]}),
提供(AuthService,{useFactory:(HttpAdvanced)=>newauthservice(HttpAdvanced),deps:[HttpAdvanced,HTTP_PROVIDERS,msgsservice]}),
提供(FormBuilderAdvanced,{useFactory:(FormBuilder,HttpAdvanced)=>new FormBuilderAdvanced(FormBuilder,HttpAdvanced),deps:[FormBuilder,HttpAdvanced]}),
提供(MsgServiceInternal,{useClass:MsgServiceInternal})
]
);
我的最新一期是:

EXCEPTION: Error during instantiation of AuthService! (HeaderBar -> AuthService).
ORIGINAL EXCEPTION: TypeError: this.http.get is not a function
我的依赖项工作起来像

HttpAdvanced        -> Http(ng2), MsgService
MsgService          -> MsgServiceInternal
AuthService         -> HttpAdvanced
FormBuilderAdvanced -> FormBuilder(ng2), HttpAdvanced
1.我是否正确使用了provide/useClass/useFactory,以及如何提供具有其他依赖关系的服务

此外,我的代码中有一个地方:

static isUserInjector(){
return(next,prev)=>Injector.resolveAndCreate([AuthService,provide(HttpAdvanced,{useClass:HttpAdvanced})]).get(AuthService.isUser();
}
因为我想有一个我提供给

@CanActivate(AuthService.isEditorInjector())
但是我不能使用构造函数注入,因为@CanActivate在类作用域之外,所以我不能在控制器内注入服务,然后像
@CanActivate(this.authService.isEditor())那样引用

2.对此有什么好的解决方案

一些代码:

@组件({
选择器:“ShowStats”,
templateUrl:'./dest/views/showStats/showStats.html',
指令:[通用指令、用户查询、管理员列表、全局权限列表、PopularTrack]
})
导出类ShowStats{
authService:authService;
构造函数(authService:authService){
this.authService=authService;
}
}
... 下一个文件。。。
@可注射()
出口级HttpAdvanced{
msgService:msgService;
http:http;
构造函数(msgService:msgService,http:http){
this.msgService=msgService;
this.http=http;
}
/*
*这是用于普通的ol'GET请求。当然是回调。
*/
公共获取(url、回调){
返回此.http.get(url).subscribe((res)=>{
让data=res.json().data;
回调(数据);
},this.msgsservice.httpErrorHandler);
}
..HttpAdvanced的其他代码
3. 导入文件的顺序对DI重要吗?我想我注意到,因为我在同一个文件中有MsgService和MsgServiceInternal,并且MsgService依赖于内部,所以我以前必须将其放入内部,但我不是100%,这与导入
的顺序相同吗

4. 因此,如果我只是这样做:

bootstrap(
应用程序,
[
表格供应商,
路由器供应商,
HTTP_提供商,
提供(LocationStrategy,{useClass:PathLocationStrategy}),
提供(RequestOptions,{useClass:DefaultRequestOptions}),
MsgService,
HttpAdvanced,
AuthService,
FormBuilderAdvanced,
MsgServiceInternal
]
);
我得到:

Cannot resolve all parameters for 'FormBuilderAdvanced'(?, ?). 
Make sure that all the parameters are decorated with Inject or have 
valid type annotations and that 'FormBuilderAdvanced' is decorated 
with Injectable.
我以前用
useFactory
删除这个错误,但现在我很困惑。这是否意味着dep没有被注入,因为它看不到它们,或者什么

表格类别:

导出类FormBuilderAdvanced{
http:HttpAdvanced;
fb:表单生成器;
构造函数(fb:FormBuilder,http:HttpAdvanced){
this.fb=fb;
this.http=http;
}
创建(controlNames:string[],submissionUrl:string,getter?:any){
返回新表单(this.fb、this.http、controlNames、submissionUrl、getter);
}
}

您的问题没有提供足够的信息来确定,但这可能足够了

bootstrap(
应用程序,
[
表格供应商,
路由器供应商,
HTTP_提供商,
提供(LocationStrategy,{useClass:PathLocationStrategy}),
提供(RequestOptions,{useClass:DefaultRequestOptions}),
//提供(MsgService,{useClass:MsgService}),
MsgService,//在不需要特殊行为的情况下很好
//提供(HttpAdvanced,{useFactory:(MsgService,HTTP_PROVIDERS)=>新的HttpAdvanced(MsgService,HTTP_PROVIDERS),deps:[MsgService,HTTP_PROVIDERS]}),
提供(Http,{useClass:HttpAdvanced});
AuthService,
提供(FormBuilder,{useClass:FormBuilderAdvanced}),
MsgServiceInternal)
]
);
如果要使类可供注入,只需将该类型添加到提供者列表中(
provide(AuthService)
并执行相同的操作)。 如果要插入与请求的类不同的类,请使用
useClass

范例

@Injectable()
导出类MyService{
构造函数(专用http:http){
}
}
如果您的提供商包含

provide(Http,{useClass:HttpAdvanced});
然后
MyService
(它依赖于
Http
)被注入
HttpAdvanced
。 确保在
HTTP\u提供程序
后面有此行,以覆盖
HTTP\u提供程序
中包含的默认
HTTP
提供程序

如果我不能
bootstrap(AppComponent, [HTTP_PROVIDERS, ROUTER_PROVIDERS,
  new Provider(Http, {
    useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
    deps: [XHRBackend, RequestOptions]
  })
]);
bootstrap(App, [
  provide(Mousetrap, { useFactory: () => new Mousetrap() })
]);