Angular2依赖注入-有意义还是只是工程过度? [英] Angular2 Dependency Injection - make sense or it's just overengineering?

查看:55
本文介绍了Angular2依赖注入-有意义还是只是工程过度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如文档所述


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

Dependency Injection is a powerful pattern for managing code dependencies

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

But does Angular's DI has any sense?

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

Let's say we have an HeroComponent living in the HeroModule, and it uses HeroService. To use it in HeroComponent we have to:


  1. 在HeroModule中导入HeroService

  2. 在模块提供程序中注入HeroService

  3. 在HeroComponent中导入HeroService

  4. 添加类型或将注入的服务添加到组件的参数中。

  1. Import HeroService in HeroModule
  2. Inject HeroService in module providers
  3. Import HeroService in HeroComponent
  4. Add type or add injected service to component's parameters.

为什么不只是


  1. 将HeroService导入HeroComponent?

我们可以导出其实例,以便我们在应用中仍然可以拥有一个单例,并且可以将webpack / karma配置为仍然能够导入模拟

We can export its instance so we can still have a singleton across our app and we can configure our webpack/karma to be still able to import mocks instead of real implementations inside our tests.

有人可以说Angular的DI使架构耦合性降低了,但这是真的吗?实际上,在Angular 1.x中,您只是在构造函数中指定了params。但是在Angular2中,您必须另外导入依赖项,并且必须从何处指定。

Someone can say Angular's DI makes architecture less tightly coupled, but is it true? In Angular 1.x indeed you just specified params in the constructor. But in Angular2 you have to import your dependency additionally, and you have to specify from where. So where is this loosely coupling?

示例:

import { Http } from 'angular2/http';

export class Login {
  constructor(http: Http) {
    http.whatever()
  }
}

要执行注射,我们必须将其导入。导入时,我们确切定义了要使用的服务。我没有发现上面和下面的示例有任何区别:

To be able to execute our injection, we have to import it. And when we import, we define exactly what service we are going to use. I don't see any difference from above and below example:

import { http } from 'angular2/http'; (instance)

export class Login {
  constructor() {
    http.whatever()
  }}


推荐答案

依赖注入与导入无关。这是关于在组件外部为您创建实例。没有DI,您的 HeroComponent 仍然需要为 HeroService 添加import语句,并且您需要手动实例化它内部 HeroComponent

Dependency injection is not about importing. It's about having the instances created for you outside of your components. Without DI your HeroComponent would still need to add the import statement for the HeroService and you'd need to manually instantiate it inside HeroComponent:

myHeroService: HeroService = new HeroService();

现在假设您需要在三个组件中使用此服务。然后,您需要在三个不同的地方写上一行。

Now imagine you need to use this service in three components. Then you'll need to write the above line in three different places.

如果因为真正的服务还没有准备好而需要使用模拟服务怎么办想要为单元测试提供模拟服务)?如果没有DI,则需要将三个组件中的代码修改为如下所示:

What if you need to use a mock service because the real one is not ready yet (or you want to have a mock service for unit tests)? Without DI you'd need to modify the code in three components to something like this:

myHeroService: MockHeroService = new MockHeroService();

有了DI,三个组件中的每一个都将具有您在上面从未修改过的相同构造函数场景,例如:

With DI each of the three components would have the same constructors that you'd never modify in the above scenario, e.g.:

class HeroComponent{

   constructor(heroService: HeroService){}
}

切换到 MockHeroService HeroModule 声明中只有一个更改(提供者):

Switching to the MockHeroService would require only one change (the provider) in the HeroModule declaration:

@NgModule({
...
providers:[provide: HeroService, useClass: MockHeroService]
})

上面的代码将指示Angular为整个模块(应用)创建一个单例。如果您决定引入多个 HeroService 实例(例如 HeroComponent1 使用 HeroService HeroComponent2 使用 MockHeroService ),然后声明提供者:[ HeroService] HeroComponent1 中:

The above code would instruct Angular to create a singleton for the entire module (app). If you decide to introduce more than one instance of HeroService (say HeroComponent1 uses HeroService, and HeroComponent2 uses MockHeroService), then just declare providers:[HeroService] in the HeroComponent1:

@Component({
...
providers:[HeroService]
})

Now Angular将为整个应用创建一个 MockHeroService 实例,并为该应用创建另一个 HeroService 实例。 HeroComponent1 及其子代。

Now Angular will create a MockHeroService instance for the entire app and another instance of the HeroService for the HeroComponent1 and its children.

请记住,您无需在任何情况下更改构造函数的签名。使用此服务的组件。

Keep in mind that you wouldn't need to change the constructors' signatures in any components that use this service.

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

Now imagine that you'd decide that in one component you want to introduce a factory function that would conditionally instantiate either HeroService or MockHeroService. You'd just declare a provider for such component using the useFactory syntax.

我可以继续:)

这篇关于Angular2依赖注入-有意义还是只是工程过度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆