如何在基于服务的Angular2项目中使用依赖注入

时间:2015-11-23 10:29:38

标签: dependency-injection angular angular-services angular-providers

问题

在过去的一周里,我一直在为Angular2项目开发一个身份验证库。这个库主要是基于服务的,几乎可以直接使用。您唯一需要做的就是将它包含在您的应用程序中并为其设置配置对象。

这里的主要服务是AuthService。此服务包括Http和另一个自定义服务。问题是这两个依赖关系都要求开发人员指出这些类的提供者。我不确定如果我有这个权利,但我已经看到他们需要导入HTTP_PROVIDERS才能使用Http的解决方案。

因此,如果我将AuthService作为依赖项导入,我仍然需要导入HTTP_PROVIDERS和自定义服务以使DI工作。

bootstrap(App, [AuthService, HTTP_PROVIDERS, CustomService]);

这让我觉得模块很容易包含在内。我想只提供导入AuthService。

到目前为止,我试过了

首先,我开始在Angular2中阅读一些关于DI的博客。正如你们大多数人所知,虽然我们在提供这些信息方面做得很好(也是EggHead.io)。我最后读了这两篇文章:

http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

阅读完之后,我认为解决方案很简单,但过了一段时间,情况似乎并非如此。我想我错过了这一点。还有工作的Spring启动,其中DI是主要的卖点,我似乎没有设法让它工作似乎很奇怪(可能是Angular2仍然在Alpha并且文档很少)。

我试过的解决方案

所以我尝试了一些我想出的解决方案,但都没有。

提供常量

我的第一个想法是查看HTTP_PROVIDERS常量,它类似于Http依赖的提供者。我最后查看了它的源代码。

https://github.com/angular/angular/blob/b0009f03d510370d9782cf76197f95bb40d16c6a/modules/angular2/http.ts#L151

之后我认为我最好尝试为我自己的班级实现这个。

export const AUTH_PROVIDERS: any[] = [
  provide(AuthService, {
    useFactory: (http, customService) => new AuthService(http, customService),
    deps: [Http, CustomService]
  })
  ,
  provide(CustomService, {
    useFactory: () => new CustomService(),
  })
];

一旦完成,我将其包含在我的引导功能中,之后我又遇到了另一个错误。

Token must be defined!

我花了一些时间试图找到问题,但我没有设法这样做。

使用注释

Angular2中的一个新功能是注释。所以我希望其中一个可以帮助我解决我的问题。 @Component@View似乎不是我需要的。我相信他们更关注功能对象的视觉方面(因为View不是我需要的东西,但是是必需的)。

下一部分看起来很奇怪,因为我无法找到这是否是注释(可能不是......)。我试着给@Provider一个机会。这导致了以下“可能”的解决方案。

@Provider({
  token: 'AuthService',
  useFactory: (http, customService) => new AuthService(http, customService)
  ...
})
export class AuthService{
  constructor(http: Http, customService, CustomService){...}
}

这只是给了我另一个错误,但这次是由Typescript编译器引发的。

error TS2348: Value of type 'typeof Provider' is not callable. Did you mean to include 'new'?

无论如何,有人可以帮助我。是朝着正确方向迈出一步的解决方案还是我做了一件可怕的错误?

提前致谢。

1 个答案:

答案 0 :(得分:2)

好吧,我发现了这个问题,但这是我以前没有想过的事情(可能是因为我主要使用Java)。 Typescript(以及最终的JavaScript)不喜欢的一件事是引用一个在你需要它的代码片段下面定义的类。我想那里必须定义'令牌!'错误来自。无论如何切换代码片解决了这个问题。

export class AuthService{...implementation...}

export const AUTH_PROVIDERS : any[] = [
  HTTP_PROVIDERS,
  provide(AuthService, {
    useFactory: (http, customService) => new AuthService(http, customService),
    deps: [Http, CustomService]
  }),
  provide(CustomService, {
    useFactory: () => new CustomService()
  })
];

希望将来可以帮助其他人。