Angular2什么是提供者,当注入器使用提供者创建服务实例时,

时间:2017-07-21 06:46:08

标签: angular dependency-injection angular-providers

我真的想知道提供商是什么?与角度2中的DI有什么关系?

app.module.ts

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
  ],
  declarations: [
    test,
  ],
  bootstrap: [ AppComponent ],
  providers: [
    userService
  ]
})
export class AppModule { }

test.component.ts

export class TestComponent implements OnInit, OnDestroy {
constructor(public user: userService)
}

在我的理解中,提供者包含服务列表令牌,注入器将使用这些服务令牌到新服务实例。服务必须在提供商处注册。

我不确定服务器实例是由注入器还是提供者创建的?如果由注入器创建,为什么我们需要提供者?

3 个答案:

答案 0 :(得分:1)

提供程序是DI创建实例或获取需要传递给构造函数或使用injector.get(..)请求的值的策略。

providers: [
  MyService // short form for
  { provide: MyService, useClass: MyService },

  // create instance of `MyServiceMock` when `MyService` is requested
  { provide: MyService, useClass: MyServiceMock },  

  // redirect to a provider for `MyService` (^^^ use this one on the previous line)
  { provide: MyServiceMock, useExisting: MyService }, 

  // custom code to create an instance
  { provide: MyService, useFactory: (a, b) => new MyMockService(a, b), deps: [Http, new Inject('foo')]},

  { provide: 'foo', useValue: 'bar' }
]

(传递给provide: ...的值是令牌来查找提供者。另一个参数是用于创建实例的策略)

当DI创建一个类的实例时,它会读取创建实例的实例或提供者的deps参数所需的类的构造函数参数,以确定需要传递给它的值。构造函数,以便创建该实例。

然后它搜索与这些必需参数值匹配的提供程序(通过构造函数参数的类型,或使用@Inject(...)装饰器分配给构造函数参数的标记。

@Injectable() 
class MyService {}

@Component(...) 
class MyComponent {
  constructor(private myService:MyService) {}
}

当Angular需要一个MyComponent实例时,它会从DI请求它,因为DI要创建一个实例,它需要一个MyService实例才能将它传递给构造函数。 DI查找MyService的提供程序并创建一个实例,或者如果之前已经创建了一个实例,则会重新使用该实例。

在注册提供程序的位置定义将哪个实例或值传递给构造函数 在此示例中,将注入组件提供程序的实例 如果Component没有providers: [MyService]行,则会注入@NgModule()中提供者的实例:

@NgModule({
  ...
  providers: [MyService],
})

@Component({
  providers: [MyService], 
}) 
class MyComponent {
  constructor(private myService:MyService) {}
}

每个子组件都有自己的注入器,它是父组件注入器的子注入器。 创建组件时,DI在组件注入器中查找提供程序,然后在父组件注入器中查找...,向上AppComponent,然后在@MgModule()注入器上查找。具有所需令牌的提供者的第一个注入器用于获取实例。 这意味着您提供提供商的地方很重要。 如果向组件添加提供程序,则会获得所提供服务的实例数,因为存在组件实例。 如果您将提供商添加到@NgModule(...) class AppModule{},那么整个应用中只会有一个实例。

延迟加载的模块增加了一些额外的复杂性。查看文档以获取更多详细信息。

答案 1 :(得分:0)

Injector不会创建服务。创建服务时,只有在要在带注释的服务中注入其他服务时才使用@Injectable注释。

每个服务都必须位于providers数组中。如果在module.ts中声明它,则每个Component中都有相同的实例。如果在Component的providers数组中声明它,那么该实例只能访问该Component及其每个子组件。

答案 2 :(得分:-2)

只是为了理解。

1-提供者是简单的类,应该是单身

2-当任何提供者(类)注入可注射组件时,它要求组件注射器通过发送该类的键来提供注入的类实例

3-如果进样器具有针对该键的单例实例,则返回实例。

4-否则它会创建实例并将该实例注册为singleton

一个非常好的例子是在不同服务中注入的Http服务