TypeScript 中的依赖注入

阅读时长 10 分钟读完

依赖注入(Dependency Injection,DI)是一种常用的设计模式,可以在不改变代码原有逻辑的情况下,提高应用程序的扩展性、可读性和可维护性。在 TypeScript 中,我们可以通过一些开源库实现依赖注入,如 InversifyJS、Typedi 等。本篇文章将以 InversifyJS 为例,来介绍 TypeScript 中的依赖注入。

InversifyJS 简介

InversifyJS 是一个轻量级的依赖注入容器,它提供了基于装饰器的语法来定义服务(Service)、绑定服务和解析服务。使用 InversifyJS,我们能够轻松地管理应用程序中的依赖关系,并保持代码的清晰和松耦合。

安装 InversifyJS

我们可以通过 npm 安装 InversifyJS,命令如下:

其中,reflect-metadata 是 TypeScript 的一个库,它用于在运行时反射元数据。

定义和绑定服务

定义服务是指将一个类标记为一个提供特定功能的服务。在 InversifyJS 中,我们使用 @injectable 装饰器来定义服务。例如:

在定义服务后,我们需要将其绑定到相应的实现类。与其它依赖注入库相似,InversifyJS 提供了很多种绑定服务的方式,这里只介绍最常用的两种:通过类和通过字符串。通过类的方式是指将类自身作为 key 绑定到实现类,如下所示:

-- -------------------- ---- -------
------ - --------- - ---- ------------
------ - ----------- - ---- -------------------------
------ - -------------- - ---- --------------------------------

----- --------- - --- ------------
--------------------------------------------

-- ----------- --------
----------------------------------------

通过字符串的方式是指将字符串作为 key 绑定到实现类。这种方式在需要将多个实现类绑定到同一个接口时非常有用。例如:

在此例中,我们通过一个常量 TYPES 来定义 key,借此将两个 UserService 的实现类绑定到不同的 key 上。

解析服务

一旦我们定义和绑定了服务,就可以在其它地方解析服务并使用它了。在 InversifyJS 中,我们使用 Container 实例来解析服务。例如:

注意,我们使用 get 方法获取服务时,需要指定 key 的类型。这可以帮助 TypeScript 在编译时检查类型。

使用构造函数注入

在上面的示例中,我们使用了 get 方法来获取 UserService 实例,并传递给其它的类。但如果 UserService 有多个依赖,在这样的情况下,我们就需要手动为所有依赖项创建实例,并将它们传递给 UserService 的构造函数:

-- -------------------- ---- -------
------ - --------- - ---- ------------
------ - ----- - ---- ----------
------ - ----------- - ---- -------------------------
------ - -------------- - ---- --------------------------------
------ - ------ - ---- -----------------

----- --------- - --- ------------
---------------------------------------------------------------
------------------------------------------------------------------------
------------------------------------------------

----- ------ - ------------------------------------
----- -------------- - ----------------------------------------------------
----- ----------- - --- --------------------------- --------

InversifyJS 支持构造函数注入的方式,使我们无需手动创建依赖项的实例,而是只需要将依赖项声明为构造函数的参数即可。像这样:

-- -------------------- ---- -------
------ - --------- - ---- ------------
------ - ----- - ---- ----------
------ - ----------- - ---- -------------------------
------ - -------------- - ---- --------------------------------
------ - ------ - ---- -----------------
------ -------------------

-------------
------ ----- ----------- -
  ------------
    ----------------------------- ------- -------- --------------- ---------------
    --------------------- ------- -------- ------- -------
  - --
-

在构造函数中,我们通过 @inject 装饰器将依赖项声明为参数。然后,在使用服务时,只需要通过 Container 实例获取服务即可:

总结

正如本文所述,InversifyJS 为 TypeScript 中的依赖注入提供了方便而又灵活的解决方案。通过定义和绑定服务,我们可以使代码更加模块化,同时使用构造函数注入方式,能够轻松管理依赖关系。希望本文对 TypeScript 开发者在依赖注入方面有所帮助。

示例代码

定义服务:

绑定服务:

通过字符串的方式绑定服务:

解析服务:

构造函数注入:

-- -------------------- ---- -------
------ - ----------- ------ - ---- ------------
------ - ----- - ---- ----------
------ - -------------- - ---- --------------------------------
------ - ------ - ---- -----------------

-------------
------ ----- ----------- -
  ------------
    ----------------------------- ------- -------- --------------- ---------------
    --------------------- ------- -------- ------- -------
  - --
-

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a7d67748841e989446e784

纠错
反馈