Angular2依赖注入 - 有意义还是只是过度工程?

时间:2016-12-11 15:00:31

标签: angular dependency-injection

正如文件所说

  

依赖注入是一种用于管理代码依赖性的强大模式

但是Angular的DI有什么意义吗?

假设我们有一个HeroComponent生活在HeroModule中,它使用HeroService。 要在HeroComponent中使用它,我们必须:

  1. 在HeroModule中导入HeroService
  2. 在模块提供程序中注入HeroService
  3. 在HeroComponent中导入HeroService
  4. 添加类型或将注入的服务添加到组件的参数中。
  5. 为什么不要

    1. 将HeroService导入HeroComponent?
    2. 我们可以导出它的实例,这样我们仍然可以在我们的应用程序中有一个单例,我们可以配置我们的webpack / karma仍然可以导入模拟而不是我们测试中的实际实现。

      有人可以说Angular的DI使得架构不那么紧密耦合,但这是真的吗?在Angular 1.x中,你确实只是在构造函数中指定了params。但是在Angular2中你必须另外导入你的依赖项,你必须从哪里指定。那松散耦合在哪里呢?

      示例:

      import { Http } from 'angular2/http';
      
      export class Login {
        constructor(http: Http) {
          http.whatever()
        }
      }
      

      为了能够执行我们的注射,我们必须导入它。当我们导入时,我们确切地定义了我们将要使用的服务。我没有看到上面和下面的示例有任何区别:

      import { http } from 'angular2/http'; (instance)
      
      export class Login {
        constructor() {
          http.whatever()
        }}
      

1 个答案:

答案 0 :(得分:1)

依赖注入与导入无关。它是关于在组件之外为您创建实例的。如果没有DI,<%= simple_form_for(@user, url: HERE_IS_SIGNUP_PATH) do |f| %> 仍然需要为HeroComponent添加import语句,并且您需要在HeroService内手动实例化它:

HeroComponent

现在想象您需要在三个组件中使用此服务。那么你需要在三个不同的地方写上面这一行。

如果您需要使用模拟服务,因为真实服务还没有准备好(或者您希望为单元测试提供模拟服务),该怎么办?如果没有DI,您需要将三个组件中的代码修改为:

myHeroService: HeroService = new HeroService();

使用DI,三个组件中的每一个都具有相同的构造函数,在上述场景中您永远不会修改,例如:

myHeroService: MockHeroService = new MockHeroService();

切换到class HeroComponent{ constructor(heroService: HeroService){} } 只需要在MockHeroService声明中进行一次更改(提供商):

HeroModule

上面的代码将指示Angular为整个模块(app)创建一个单例。如果您决定引入多个@NgModule({ ... providers:[provide: HeroService, useClass: MockHeroService] }) 的实例(例如HeroService使用HeroComponent1HeroService使用HeroComponent2),则只需声明MockHeroService } providers:[HeroService]

HeroComponent1

现在,Angular会为整个应用创建一个@Component({ ... providers:[HeroService] }) 个实例,为MockHeroService及其子级创建另一个HeroService实例。

请记住,您不需要更改构造函数&#39;使用此服务的任何组件中的签名。

现在想象一下,您决定在一个组件中引入一个有条件地实例化HeroComponent1HeroService的工厂函数。您只需使用MockHeroService语法声明此类组件的提供程序。

我可以继续:)