首页 > 其他分享 >Angular 应用开发中 Injection Token 的使用方法介绍

Angular 应用开发中 Injection Token 的使用方法介绍

时间:2023-09-24 21:55:16浏览次数:27  
标签:依赖 Token InjectionToken import Injection CONFIG Angular 注入

Angular是一个流行的前端JavaScript框架,它提供了一种强大的方式来构建单页应用程序(SPA)。在Angular中,依赖注入(Dependency Injection,DI)是一项关键的功能,它允许我们有效地管理应用程序中的依赖关系。Angular的依赖注入系统使用InjectionToken来实现某些特殊的依赖注入需求。在本文中,我将详细解释InjectionToken的作用,并提供示例以说明其在Angular应用中的实际用途。

什么是依赖注入?

在深入了解InjectionToken之前,让我们首先了解什么是依赖注入。依赖注入是一种设计模式,它允许我们将一个对象的依赖关系(例如,服务或配置)注入到另一个对象中,而不需要硬编码这些依赖关系。这样做的好处包括:

  1. 可维护性:通过将依赖关系注入到组件中,我们可以轻松更改这些依赖项,而不必修改大量的代码。

  2. 可测试性:我们可以轻松地为组件提供模拟的依赖项,以进行单元测试,而无需实际创建这些依赖项的实例。

  3. 松耦合:依赖注入帮助我们实现松耦合,使各个组件之间的关系更加灵活。

在Angular中,依赖注入是内置的,Angular的依赖注入容器负责管理依赖项的创建和生命周期。

为什么需要InjectionToken?

通常情况下,Angular的依赖注入系统可以自动解析依赖项的类型并为其创建实例。例如,如果您需要在组件中使用一个服务,只需将该服务的类型声明为该组件的构造函数参数,Angular将会自动创建该服务的实例并注入到组件中,如下所示:

import { Component } from '@angular/core';
import { MyService } from './my-service';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.html',
})
export class MyComponent {
  constructor(private myService: MyService) {
    // 使用myService
  }
}

但是,有时候我们需要注入的依赖项不是一个类的实例,而是一个配置项、字符串、或其他非类的值。这就是InjectionToken的用武之地,它允许我们将非类的值作为依赖项注入到组件或服务中。

InjectionToken的作用

InjectionToken的作用是定义一个标识符,用于标识依赖项。它允许我们将任何值注入到Angular组件或服务中,而不仅仅是类的实例。通常情况下,我们会在应用程序中的某个地方创建InjectionToken,然后在需要注入该值的地方使用它。

以下是InjectionToken的主要作用:

  1. 唯一性标识InjectionToken是一个唯一的标识符,确保依赖项的唯一性。这对于防止依赖项的混淆或冲突非常重要。

  2. 非类依赖注入InjectionToken允许我们注入任何值,而不仅仅是类的实例。这在配置、常量、字符串等场景中非常有用。

  3. 提供器配置:通过提供器配置,我们可以告诉Angular如何为InjectionToken提供依赖项的实例。这使得我们可以在不同的上下文中为InjectionToken提供不同的值。

现在,让我们通过一些示例详细说明InjectionToken的用法和作用。

示例一:注入配置

假设我们有一个应用程序,它需要根据用户的首选语言加载不同的国际化配置。我们可以使用InjectionToken来注入当前用户的首选语言配置。首先,我们需要创建一个InjectionToken来表示这个配置:

import { InjectionToken } from '@angular/core';

export const LANG_CONFIG = new InjectionToken<string>('langConfig');

上面的代码创建了一个名为LANG_CONFIGInjectionToken,它表示一个字符串类型的依赖项,用于存储语言配置。

接下来,我们可以在Angular模块中配置如何提供这个依赖项的实例:

import { NgModule } from '@angular/core';
import { LANG_CONFIG } from './config.tokens';

@NgModule({
  providers: [
    {
      provide: LANG_CONFIG,
      useValue: 'en-US' // 默认语言配置
    }
  ]
})
export class AppModule { }

在上面的代码中,我们在模块的提供器中配置了LANG_CONFIG的默认值为en-US。这意味着如果没有其他地方提供LANG_CONFIG的实际值,它将默认为en-US

现在,我们可以在组件中注入这个配置,并根据用户的首选语言进行相应的操作:

import { Component, Inject } from '@angular/core';
import { LANG_CONFIG } from './config.tokens';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.html',
})
export class MyComponent {
  constructor(@Inject(LANG_CONFIG) private langConfig: string) {
    // 使用langConfig来加载对应的国际化资源
  }
}

在上面的组件中,我们使用@Inject装饰器来注入LANG_CONFIG,然后可以根据用户的首选语言配置执行相应的操作。

这个示例展示了如何使用InjectionToken来注入应用程序的配置项,而不是类的实例

示例二:自定义注入令牌

除了用于配置,InjectionToken还可以用于自定义依赖注入的标识符。假设我们有一个应用程序,它需要同时加载两个不同版本的某个服务,我们可以使用不同的InjectionToken来区分它们。

首先,我们创建两个不同的InjectionToken来表示这两个版本的服务:

import { InjectionToken } from '@angular/core';

export const SERVICE_V1 = new InjectionToken('service_v1');
export const SERVICE_V2 = new InjectionToken('service_v2');

然后,我们可以在模块中配置这两个服务的提供方式:

import { NgModule } from '@angular/core';
import { SERVICE_V1, SERVICE_V2 } from './service.tokens';
import { ServiceV1 } from './service-v1';
import { ServiceV2 } from './service-v2';

@NgModule({
  providers: [
    {
      provide: SERVICE_V1,
      useClass: ServiceV1
    },
    {
      provide: SERVICE_V2,
      useClass: ServiceV2
    }
  ]
})
export class AppModule { }

在上面的代码中,我们为SERVICE_V1提供了ServiceV1的实现,为SERVICE_V2提供了ServiceV2的实现。

现在,我们可以在组件中注入这两个服务,并使用它们的不同版本:

import { Component, Inject } from '@angular/core';
import { SERVICE_V1, SERVICE_V2 } from './service.tokens';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.html',
})
export class MyComponent {
  constructor(
    @Inject(SERVICE_V1) private serviceV1: any,
    @Inject(SERVICE_V2) private serviceV2: any
  ) {
    // 使用serviceV1和serviceV2的不同版本
  }
}

在上面的组件中,我们使用不同的InjectionToken注入了两个不同版本的服务,这使得我们可以在同一个应用程序中使用它们的不同实现。

示例三:跨模块通信

有时,我们希望在不同的模块之间共享某些值,例如应用程序的全局配置。InjectionToken可以用于实现跨模块的通信。

假设我们有一个核心模块,它包含了一些全局配置信息,我们希望其他模块能够访问这些配置信息。首先,我们在核心模块中创建一个InjectionToken来表示全局配置:

import { InjectionToken } from '@angular/core';

export const GLOBAL_CONFIG = new InjectionToken('global_config');

然后,在核心模块中配置全局配置的值:

import { NgModule } from '@angular/core';
import { GLOBAL_CONFIG } from './core.tokens';

@NgModule({
  providers: [
    {
      provide: GLOBAL_CONFIG,
      useValue: {
        apiUrl: 'https://api.example.com',
        debugMode: false
      }
    }
  ]
})
export class CoreModule { }

现在,任何需要访问全局配置的模块或组件都可以注入GLOBAL_CONFIG并访问全局配置的值:

import { Component, Inject } from '@angular/core';
import { GLOBAL_CONFIG } from './core.tokens';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.html',
})
export class MyComponent {
  constructor(@Inject(GLOBAL_CONFIG) private globalConfig: any) {
    // 访问全局配置的值,例如globalConfig.apiUrl
  }
}

这个示例展示了如何使用InjectionToken在不同的模块之间共享全局配置信息。

总结

InjectionToken是Angular依赖注入系统的一个重要组成部分,它允许我们注入非类依赖项,自定义依赖注入的标识符,并实现跨模块通信。通过合理使用InjectionToken,我们可以提高Angular应用程序的可维护性、可测试性,并实现松耦合的设计。希望本文中的示例有助于您更好地理解InjectionToken的作用和用法,以在您的Angular项目中充分发挥其威力。

标签:依赖,Token,InjectionToken,import,Injection,CONFIG,Angular,注入
From: https://www.cnblogs.com/sap-jerry/p/17726773.html

相关文章

  • kubepi加入集群,生成token
    防丢失https://www.cnblogs.com/Chinori/p/17506348.html kubectlcreatesakubepi-user--namespacekube-systemkubectlcreateclusterrolebindingkubepi-user--clusterrole=cluster-admin--serviceaccount=kube-system:kubepi-userkubectl-nkube-systemcreatetoke......
  • Angular 应用程序的 Hydration 概念详解
    Angular应用程序的Hydration概念Hydration概念是Angular应用程序中的一个关键概念,它涉及到Angular框架在客户端渲染(Client-siderendering,CSR)中的运作方式。要深入理解Hydration,首先需要了解CSR和SSR(Server-siderendering,服务器端渲染)之间的基本区别,以及Angular是如何利用Hydra......
  • Angular 16+ 基础教程 – 开篇和目录
    前言前阵子我开始写 Angular复习与进阶系列,写着写着,发现写不下去。思来想去,感觉原因是主题定的不好。复习与进阶,意味着看的人就要有基础,但是这个基础到底要多少又说不清楚,更糟糕的是这两年Angular团队重组后尽然开始做新功能了,而且有越做越多的迹象,所以这个说这个基础更加......
  • Token持久化存储
    Token持久化存储我们之前使用SpringSecurity时,remember-me的Token是支持持久化存储的,而我们当时是存储在数据库中,那么Token信息能否存储在缓存中呢,当然也是可以的,我们可以手动实现一个://实现PersistentTokenRepository接口@ComponentpublicclassRedisTokenRepositoryimplem......
  • 【项目心得】关于Angular中使用Cookie
    今天写一个Angular前端项目时遇到需要使用Cookie的场景,bing寻找解决办法根据bing搜索第一条的方法,使用了一个名为”ngx-cookie-service“的库,结果方才一导入,就提示报错,报错信息如下:Error:Uncaught(inpromise):Error:NG0203:inject()mustbecalledfromaninjec......
  • 完美解决ParserError: Error tokenizing data. C error: Expected 2 fields in line 5
    完美解决ParserError:Errortokenizingdata.Cerror:Expected2fieldsinline53,saw3文章目录报错问题解决方法声明报错问题之前在工作中遇到过这个坑,记录一下问题以及解决方法,不一定针对所有情况都能用,但是可以供大家参考。问题描述如下:ParserError:Errortokenizing......
  • 进程注入之Portable Executable Injection,PE注入的核心是创建远程线程,注意重定位表修
     PE(Portable Executable)注入是一种常见的代码注入技术,主要用于在目标进程中执行恶意代码。以下是PE注入的基本流程:1. 获取当前PE映像的基地址:使用GetModuleHandle(NULL)函数获取当前PE映像(即要注入的代码)的基地址。2. 复制PE映像:使用VirtualAlloc函数在当前进程中分配一块新......
  • Denpendcy Injection 8.0新功能——KeyedService
    DenpendcyInjection8.0新功能——KeyedService本文只介绍.NETDenpendcyInjection8.0新功能——KeyedService,假定读者已熟练使用之前版本的功能。注册带Key的类8.0之前,注册一个类往往是AddSingleton<IFoo,Foo>(),8.0添加了一个新功能:“可以注册一个带Key的类”AddKeyedSin......
  • Token和session的区别
    Token和session的核心区别点:session需要将登录记录信息存储在服务器,中心化存储,服务器挂了,session信息可能丢失。Session类似入职后每次进出办公楼,都需要携带工卡,刷卡才能进门,门禁需要将工卡和数据库中数据进行比对。token通常具有自证功能,服务器一般不需要存储用户登录状态信息。......
  • Java框架中常用的几种成熟的token生成框架对比
    Java框架中常用的几种成熟的token生成框架对比Java框架中常用的几种成熟的token生成框架有:SpringSecurity:一个基于Spring的安全框架,提供了声明式的安全访问控制解决方案,支持多种认证和授权机制,如OAuth2.0、JWT等。ApacheShiro:一个轻量级的Java安全框架,提供了身份认证......