Open haizhilin2013 opened 1 month ago
在 Angular 中,提供者(Provider)、服务(Service)和工厂(Factory)是依赖注入(Dependency Injection)机制的核心概念。它们之间的区别在于它们的定义方式、使用场景以及创建实例的方式。下面详细解释这些概念及其区别。
提供者是 Angular 依赖注入系统中用于配置如何创建和提供依赖对象的机制。提供者可以在模块、组件或指令的 providers
数组中配置。
类提供者(Class Provider):
使用类来定义提供者。Angular 会使用 new
操作符来实例化这个类。
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() { }
}
值提供者(Value Provider): 使用一个预定义的值来提供依赖。
const MY_VALUE = { key: 'value' };
@NgModule({
providers: [{ provide: 'MY_VALUE', useValue: MY_VALUE }]
})
export class AppModule { }
工厂提供者(Factory Provider): 使用一个工厂函数来创建依赖对象。
export function myFactory() {
return new MyService();
}
@NgModule({
providers: [{ provide: MyService, useFactory: myFactory }]
})
export class AppModule { }
别名提供者(Alias Provider): 使用另一个令牌来提供依赖对象,即依赖对象的别名。
@NgModule({
providers: [{ provide: 'AnotherService', useExisting: MyService }]
})
export class AppModule { }
服务是一个类,通常用来封装应用程序的业务逻辑和数据访问。服务类使用 @Injectable
装饰器来标记,以便 Angular 的依赖注入系统可以注入它们。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MyService {
constructor() { }
getData() {
return 'some data';
}
}
在上面的示例中,MyService
被定义为一个服务,并且通过 providedIn: 'root'
选项在根注入器中提供,这意味着它是一个单例服务。
工厂是一个函数,用于创建和返回依赖对象。工厂函数可以包含一些逻辑,以便根据需要动态创建对象。工厂通常与工厂提供者一起使用。
export function myFactory() {
return new MyService();
}
@NgModule({
providers: [{ provide: MyService, useFactory: myFactory }]
})
export class AppModule { }
在上面的示例中,myFactory
函数被用作工厂函数,通过 useFactory
提供给 MyService
。
提供者(Provider):
providers
数组配置。服务(Service):
@Injectable
装饰器的类。工厂(Factory):
通过理解这些概念及其区别,你可以更好地设计和构建 Angular 应用程序的依赖注入系统,提升代码的可维护性和重用性。
对于4种类型的提供者可能会有点迷惑,接下来通过4个想详细的例子有个更清晰的了解:
当然,实际例子能更好地帮助理解提供者的四种类型及其使用场景。下面是一些具体的例子:
场景:你有一个服务类 LoggingService
,它负责记录日志信息。你希望在应用程序的不同部分使用这个服务。
// logging.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LoggingService {
log(message: string) {
console.log(message);
}
}
// app.component.ts
import { Component } from '@angular/core';
import { LoggingService } from './logging.service';
@Component({
selector: 'app-root',
template: '<h1>My App</h1>'
})
export class AppComponent {
constructor(private loggingService: LoggingService) {
this.loggingService.log('AppComponent initialized');
}
}
场景:你有一些静态的配置信息,例如 API 的基 URL,你希望在应用程序中共享这些配置。
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
const API_CONFIG = { baseUrl: 'https://api.example.com' };
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [{ provide: 'API_CONFIG', useValue: API_CONFIG }],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component, Inject } from '@angular/core';
@Component({
selector: 'app-root',
template: '<h1>My App</h1>'
})
export class AppComponent {
constructor(@Inject('API_CONFIG') private config: any) {
console.log('API Base URL:', this.config.baseUrl);
}
}
场景:你有一个服务 UserService
,它需要根据某些条件动态创建。比如,你希望在服务创建时注入一个依赖 HttpClient
,并根据环境变量选择不同的 API 端点。
// user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class UserService {
constructor(private http: HttpClient, private apiUrl: string) { }
getUser() {
return this.http.get(`${this.apiUrl}/user`);
}
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { AppComponent } from './app.component';
import { UserService } from './user.service';
export function userServiceFactory(http: HttpClient) {
const apiUrl = environment.production ? 'https://api.prod.com' : 'https://api.dev.com';
return new UserService(http, apiUrl);
}
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [{ provide: UserService, useFactory: userServiceFactory, deps: [HttpClient] }],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-root',
template: '<h1>My App</h1>'
})
export class AppComponent {
constructor(private userService: UserService) {
this.userService.getUser().subscribe(user => console.log(user));
}
}
场景:你有一个服务 AuthService
,它实现了一个 IAuthService
接口。你希望通过接口注入服务,以便将来可以轻松替换实现。
// auth.service.ts
import { Injectable } from '@angular/core';
export interface IAuthService {
login(username: string, password: string): void;
}
@Injectable({
providedIn: 'root'
})
export class AuthService implements IAuthService {
login(username: string, password: string) {
console.log('User logged in');
}
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AuthService, IAuthService } from './auth.service';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [{ provide: IAuthService, useExisting: AuthService }],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
import { IAuthService } from './auth.service';
@Component({
selector: 'app-root',
template: '<h1>My App</h1>'
})
export class AppComponent {
constructor(private authService: IAuthService) {
this.authService.login('user', 'password');
}
}
这些实际例子展示了不同提供者类型的具体应用场景,帮助你理解它们的使用方式和存在的理由。
第1879天 请说说在Angular中提供者,服务和工厂之间有什么区别?
3+1官网
我也要出题