我真的很想知道什么是提供者? 与 Angular2 中的 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)
}
在我的理解中,提供者包含服务列表令牌,注入器将使用这些服务令牌到新的服务实例。 服务必须在提供程序中注册。
我不确定服务实例是由注入器还是提供者创建的?如果由注射器创建,为什么我们需要提供程序?
提供程序是 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
并创建一个实例,或者如果以前已创建一个实例,则会重用此实例。
提供程序的注册位置定义将哪个实例或值传递给构造函数。
在此示例中,将注入组件提供程序的实例。
如果组件没有providers: [MyService]
行,则将注入来自@NgModule()
中的提供程序的实例:
@NgModule({
...
providers: [MyService],
})
@Component({
providers: [MyService],
})
class MyComponent {
constructor(private myService:MyService) {}
}
每个子组件都有自己的注入器,该注入器是父组件注入器的子注入器。 创建组件时,DI 在组件注入器中查找提供程序,然后在父组件注入器中查找提供程序,...,太AppComponent
,然后在@MgModule()
注入器中查找提供程序。具有所需令牌提供程序的第一个注入器用于获取实例。 这意味着在何处提供提供程序很重要。 如果将提供程序添加到组件,则获得所提供服务的实例数与组件实例数一样多。 如果仅将提供程序添加到@NgModule(...) class AppModule{}
则整个应用程序中将只有一个实例。
延迟加载的模块增加了一些额外的复杂性。查看文档以获取更多详细信息。
该服务不是由 Injector 创建的。创建服务时,仅当您要在带注释的服务中注入另一个服务时,才使用@Injectable注释。
每个服务都必须在提供程序数组中。如果您在 module.ts 中声明它,您将在每个组件中具有相同的实例。如果在组件的提供程序数组中声明它,则该实例将只能访问该组件及其每个子组件。
只是为了理解。
1-提供程序是简单的类,应该是单例的
2-当任何提供程序(类(注入到可注入组件中时,它要求组件的注入器通过发送该类的键来提供注入的类实例
3-如果注入器针对该键具有该单例实例,则返回该实例。
4-否则,它会创建实例并将该实例注册为单例
一个很好的例子是注入不同服务的 Http 服务