You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 13如何根据local/QA环境动态注入本地服务与API服务

Angular 13 动态注入服务实现方案

步骤1:定义公共服务接口

首先为两个API服务定义统一的调用接口,保证两者对外暴露的方法签名一致:
api.interface.ts

import { Observable } from 'rxjs';
import { LoginRequest } from '../login/login-request';

export interface IApiService {
  userLogin(loginRequest?: LoginRequest): Observable<any>;
  getUserList(): Observable<any>;
}

步骤2:调整两个API服务实现接口

分别修改api-local.service.ts和api.service.ts,实现上述接口,对齐方法名和参数:

修改后 api-local.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { LoginRequest } from '../login/login-request';
import { IApiService } from './api.interface';

@Injectable({
  providedIn: 'root'
})
export class ApiLocalService implements IApiService {

  constructor(private httpClient: HttpClient) { }
  
  private headers = new HttpHeaders({
    'Content-Type': 'application/json; charset=utf-8',
    'Accept': 'application/json, text/plain'
  });

  userLogin(): Observable<any>{
    console.log("inside LOCAL API service");
    return this.httpClient.get('../assets/data/login.json', {headers:this.headers});
  }

  getUserList(): Observable<any>{
    return this.httpClient.get('../assets/data/userList.json' , { headers: this.headers })
  }
}

修改后 api.service.ts

import { Inject, Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { LoginRequest } from '../login/login-request';
import { EnvironmentConfig, ENV_CONFIG } from './environment-config.interface';
import { IApiService } from './api.interface';

@Injectable({
  providedIn: 'root'
})
export class ApiService implements IApiService {
  public apiUrl: string;

  constructor(@Inject(ENV_CONFIG) config: EnvironmentConfig,private httpClient: HttpClient,) {
    this.apiUrl = `${config.environment.baseUrl}`;
   }
  
  private headers = new HttpHeaders({
    'Content-Type': 'application/json; charset=utf-8',
    'Accept': 'application/json, text/plain'
  });

  userLogin(loginRequest: LoginRequest): Observable<any>{
    console.log("inside QA API service");
    return this.httpClient.post(`${this.apiUrl}/auth-service/login`, loginRequest, {headers:this.headers});
  }

  getUserList(): Observable<any>{
    return this.httpClient.get(`${this.apiUrl}/user/list` , { headers: this.headers })
  }
}

步骤3:修改AuthService实现动态注入

修改auth-service.ts,使用Angular的Injector动态获取服务实例,无需硬编码注入固定服务:

修改后核心代码

import { EventEmitter, Injectable, Output, Injector } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { HttpClient } from '@angular/common/http';

import { LoginRequest } from '../login/login-request';
import { LoginResponse } from '../login/login-response';
import { LocalStorageService } from 'ngx-webstorage';
import { map, tap ,catchError} from 'rxjs/operators';
import { environment } from 'src/environments/environment';

import { IApiService } from './api.interface';
import { ApiLocalService } from './api-local.service';
import { ApiService } from './api.service';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private API_URL = environment.API_URL;
  private roles: Array<string> = [];
  private apiService: IApiService; // 公共接口类型的服务实例

   
  @Output() loggedIn: EventEmitter<boolean> = new EventEmitter();
  @Output() username: EventEmitter<string> = new EventEmitter();
  @Output() admin: EventEmitter<boolean> = new EventEmitter();
  @Output() superAdmin: EventEmitter<boolean> = new EventEmitter();
  @Output() client: EventEmitter<boolean> = new EventEmitter();

  refreshTokenPayload = {
    refreshToken: this.getRefreshToken(),
    username: this.getUserName()
  }
  constructor(
    private httpClient: HttpClient,
    private localStorage: LocalStorageService,
    private injector: Injector // 注入Angular注入器
  ) { 
    // 初始化时根据环境判断要使用的服务实例
    this.apiService = environment.env === 'local'
      ? this.injector.get(ApiLocalService)
      : this.injector.get(ApiService);
}
    
 
adminLogin(loginRequest: LoginRequest): Observable<boolean> {
  console.log("loginrequest:"+loginRequest);
  // 调用动态获取的服务的统一登录方法
  return this.apiService.userLogin(environment.env === 'qa' ? loginRequest : undefined)
    .pipe(map(data => {
      console.log(data)
      if(data.roles.find((role: string) => role !='ROLE_SUPER_ADMIN' && role !='ROLE_ADMIN' && role !='ROLE_CLIENT')){
        return false;
      }else{
      this.localStorage.store('authenticationToken', data.authenticationToken);
    this.localStorage.store('username', data.username);
    this.localStorage.store('refreshToken', data.refreshToken);
    this.localStorage.store('expiresAt', data.expiresAt);
    this.localStorage.store('roles', JSON.stringify(data.roles));
    this.loggedIn.emit(true);
    this.username.emit(data.username);
    if(data.roles.find((role: string) => role =='ROLE_ADMIN')){
      this.admin.emit(true);
    }
    if(data.roles.find((role: string) => role =='ROLE_SUPER_ADMIN')){
       this.superAdmin.emit(true);
    }
    if(data.roles.find((role: string) => role =='ROLE_CLIENT')){
      this.client.emit(true);
   }
    
    return true;
      }
    }));
  }
  // 其他原有方法保持不变
}

配置校验

确保你的环境配置文件environment.ts中已添加环境标识字段:

  • 本地环境配置:env: 'local'
  • QA环境配置:env: 'qa'

后续如需新增其他环境,仅需要修改构造函数中的服务判断逻辑即可,无需改动业务调用代码,可扩展性更高。

内容的提问来源于stack exchange,提问作者Shruthy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:27:02