Loading [MathJax]/jax/output/CommonHTML/config.js
社区首页 >问答首页 >如何通过本机TypeScript实现延迟加载的依赖注入?

如何通过本机TypeScript实现延迟加载的依赖注入?
EN

Stack Overflow用户
提问于 2022-10-22 23:15:10
回答 1查看 140关注 0票数 5

框架开发人员喜欢通过实现依赖项注入概念来吹嘘。下面的实现是本机的、简单的和类型安全的.

代码语言:javascript
代码运行次数:0
复制
// All below gateways and services are the abstractions
type ApplicationDependencies = Readonly<{
  gateways: Readonly<{
    category: CategoryGateway;
    product: ProductGateway;
  }>;
  services: Readonly<{
    authentication: AuthenticationService;
  }>;
}>;


export default abstract class DependenciesInjector {

  private static dependencies: ApplicationDependencies | null = null;

  public static setDependencies(dependencies: ApplicationDependencies): void {
    DependenciesInjector.dependencies = dependencies;
  }

  private static getDependencies(): ApplicationDependencies {

    if (DependenciesInjector.dependencies === null) {
      throw new Error("The DependenciesInjector has not been initialized");
    }


    return DependenciesInjector.dependencies;
  }


  public static get gateways(): ApplicationDependencies["gateways"] {
    return DependenciesInjector.getDependencies().gateways;
  }

  public static get services(): ApplicationDependencies["services"] {
    return DependenciesInjector.getDependencies().services;
  }
}

初始化必须在入口点执行:

代码语言:javascript
代码运行次数:0
复制
ApplicationDependencies.setDependencies({
  gateways: {
    category: new CategoryAxiosGateway(),
    product: new ProductAxiosGateway()
  },
  services: {
    authentication: new AuthenticationCognitoService()
  }
});

现在,可以将这些依赖项注入为

代码语言:javascript
代码运行次数:0
复制
import { Vue as VueComponent, Options as VueComponentConfiguration } from "vue-property-decorator";

@VueComponentConfiguration({})
export default class CategoriesManager extends VueComponent {
  
  private readonly categoryGateway!: CategoryGateway;

  // It's O'K from the viewpoint of TypeScript, but this way `categoryGateway` will become to
  //    reactive field (Vue's 'data') which could be undesirably
  // private readonly categoryGateway!: CategoryGateway = DependenciesInjector.gateways.category;

  public created(): void {
    this.categoryGateway = DependenciesInjector.gateways.category;
  }
}

以上方法对于大多数控制台和服务器应用程序来说已经足够好了,但是对于前端应用程序来说则不是最优的。它可能是数十个依赖项,一旦访问应用程序的任何页面,它们都将立即初始化。

如何解决这个问题?概念上的答案是“模块动态加载的操作”AKA“延迟加载”。我想问的是,在不改变注入方法的情况下(如上述Vue组件所示),它能否实现?如果是--如何实现?

现有实现的示例

Vue-路由器

Vue路由器支持开箱即入的动态导入,这意味着您可以用动态导入替换静态导入:

导入(‘/视图/UserDetails.vue’) const路由器= createRouter({ // .路由:{ path:‘/user/:id’,组件: UserDetails },})‘’

vue-router documentation

因此,对组件的访问不会改变。

NestJS

为了按需加载模块,

提供了可以以正常方式注入到类中的LazyModuleLoader类:

构造函数(私有lazyModuleLoader: LazyModuleLoader) {}

NestJS documentation

思考我的案子的方式

我们不能像以前那样设置依赖项。就像

代码语言:javascript
代码运行次数:0
复制
ApplicationDependencies.setDependencies({
  gateways: {
    category: async (): Promise<CategoryGateway> => import("@Data/Gateways/CategoryAxiosGateway"),
    product: async (): Promise<ProductGateway> => import("@Data/Gateways/ProductAxiosGateway")
  },
  services: {
    authentication: async (): Promise<AuthenticationService> => import ("@Services/Gateways/ProductAxiosGateway")
  }
});

只是草案而已。我们需要处理正确的类型、默认/非默认导入等等。我们还需要重写DependenciesInjectorApplicationDependencies。但是如何访问这些依赖项呢?

代码语言:javascript
代码运行次数:0
复制
@VueComponentConfiguration({})
export default class CategoriesManager extends VueComponent {
  
  private readonly categoryGateway!: CategoryGateway;

  public async created(): void {
    this.categoryGateway = await DependenciesInjector.gateways.category;
  }
}

我需要使crated方法异步。我能否实现延迟加载,如保留上面的Vue组件,就像在前面的示例中一样?如果没有,哪一种最好的实现是可能的?

请注意,对这个主题的答案需要对概念的解释,而不是第三个-部分解决方案的建议。

EN

回答 1

Stack Overflow用户

发布于 2022-11-13 01:43:41

我也遇到了同样的问题,所以我为此编写了DI lib。就像一种魅力。对我和我的团队来说很有成效。

它被称为iti,它有一些很好的响应绑定,所以应该可以将它们移植到Vue。

基本上,它是这样工作的:

您还可以检查文档上的React示例:

https://itijs.org/docs/with-react/react-full#async-request-for-single-item-in-iti

代码语言:javascript
代码运行次数:0
复制
  import { createContainer } from "iti"

  // blue.ts
  // export class Blue implements IColor {}
  // rainbow-service.ts
  // export class RainbowSegment { constructor(c: IColor) {} }

  // async imports, no trace in runtime
  export const container = createContainer()
    .add(() => ({
      blue: async () => {
        const { Blue } = await import("./blue")
        return new Blue()
      },
    }))
    .add((ctx) => ({
      blueRainbowSegment: async () => {
        const { RainbowSegment } = await import("./rainbow-service")
        return new RainbowSegment(ctx.blue)
      },
    }))

  const blueSegment = await container.items.blueRainbowSegment
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74169292

复制
相关文章
MVC 控制器中传递dynamic(对象) 给视图
 有时候不想重新定义一个实体,则使用 dynamic 来定义匿名类型。 //匿名类型 传递到前台 Model dynamic viewModel = n
纯粹是糖
2018/03/14
8810
MVC 控制器中传递dynamic(对象) 给视图
ASP.NET MVC 5 - 将数据从控制器传递给视图
在我们讨论数据库和数据模型之前,让我们先讨论一下如何将数据从控制器传递给视图。控制器类将响应请求来的URL。控制器类是给您写代码来处理传入请求的地方,并从数据库中检索数据,并最终决定什么类型的返回结果会发送回浏览器。视图模板可以被控制器用来产生格式化过的HTML从而返回给浏览器。 控制器负责给任何数据或者对象提供一个必需的视图模板,用这个视图模板来Render返回给浏览器的HTML。最佳做法是:一个视图模板应该永远不会执行业务逻辑或者直接和数据库进行交互。相应的,一个视图模板应该只和控制器所提供的数据进行交
葡萄城控件
2018/01/10
5K0
ASP.NET MVC 5 - 将数据从控制器传递给视图
play framework - 初识
研发代码框架是play-framework框架,想看代码的话,需要学习下play框架。IDE工具的话之前一直用的idea,所以本文涉及的idea play的配置 和 一些play的简单知识
千往
2018/12/27
1.4K0
play framework - 初识
从视图到控制器的传值方法(表单)
Views中: 将数据提交到某个控制器的方法中,在该方法中去做处理 <form action="/控制器/get"method=“post”> 姓名:<input type="text" name="SName"/> //SName是属性名称 性别:<input type="radio" name="sex" value="男"/>; <input type="radio" name="sex" value="女"/> //sex是属性名称 <input type="submit" valu
wfaceboss
2019/04/08
1.9K0
利用fluorineFx将DataTable从.Net传递到Flash
FluorineFx自带的示例都不错,就是有点不简洁,下面的代码基本上已经最简版了(环境vs2010) 1、先创建一个Web Application,然后添加FluorineFx以及FluorineFx.ServiceBrowser的引用 这二个程序集的默认位置在: C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.dll C:\Program Files (x86)\FluorineFx\Bin\net\3.5\FluorineFx.Serv
菩提树下的杨过
2018/01/23
2.4K0
利用fluorineFx将DataTable从.Net传递到Flash
SpringMVC传递模型数据到视图
要求:处理方法返回值类型为 ModelAndView。在方法体中我们通过该ModelAndView对象添加模型数据。
Tim在路上
2020/08/04
8150
Asp.Net MVC4入门指南(5):从控制器访问数据模型
在本节中,您将创建一个新的MoviesController类,并在这个Controller类里编写代码来取得电影数据,并使用视图模板将数据展示在浏览器里。 在开始下一步前,先Build一下应用程序(生成应用程序)(确保应用程序编译没有问题) 用鼠标右键单击Controller文件夹,并创建一个新的 MoviesController控制器。当Build成功后,会出现下面的选项。设定以下选项: · 控制器名称: MoviesController.(这是默认值)。 · 模板: MVC Controller wit
葡萄城控件
2018/01/10
4.2K0
Asp.Net MVC4入门指南(5):从控制器访问数据模型
ASP.NET MVC 5 -从控制器访问数据模型
在本节中,您将创建一个新的MoviesController类,并在这个Controller类里编写代码来取得电影数据,并使用视图模板将数据展示在浏览器里。 在开始下一步前,先Build一下应用程序(生
葡萄城控件
2018/01/10
5.9K0
ASP.NET MVC 5 -从控制器访问数据模型
错误页面定制与视图传递多个参数
一、错误页面定制 视图函数 <span class="hljs-meta">@app.errorhandler(404)</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">page_not_found</span><span class="hljs-params">(e)</span>:</span> <span class="hljs-keyword">
星哥玩云
2022/09/14
1K0
ASP.NET MVC学习笔记05模型与访问数据模型
上一篇使用的M模型,并不是真正意义上的Model,现在来添加一些类,并将这些类用来管理数据库中数据(电影)。而这些类,就是ASP.NET MVC中的Model(模型)。 ---- 而这里也将使用.NET Framework数据访问技术Entity Framework 来定义和使用这些模型类。Entity Framework(简称为EF)是支持代码优先(Code First)的开发模式。代码优先允许通过编写简单的类来创建对象模型,然后从类创建数据库。 添加模型类 在解决方案资源管理器中,右键单击Mode
李郑
2018/03/01
2.4K0
ASP.NET MVC学习笔记05模型与访问数据模型
maven编译时出现There are test failures
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.10:test (default-test) on project web_nanchang: There are test failures. [ERROR] [ERROR] Please refer to E:\maven\web_nanchang\target\surefire-reports for the individual test r
闵开慧
2018/03/30
3.6K0
体验 Scala 语言的 Play Web 框架
在本文中将介绍 Scala 的 Play Web 开发框架。我们将会学习如何创建一个 Play 项目,使用开发工具生成我们的第一个项目以及实现自定义的功能,另外还将体验一下 Play 框架的测试能力。
RiemannHypothesis
2022/09/28
2K0
Hadoop搭建,上传文件时出现错误,没有到主机的路由
解决方案: (1)从namenode主机ping其它slaves节点的主机名(注意是slaves节点的主机名),如果ping不通,原因可能是namenode节点的/etc/hosts 未配置主机名与IP地址的映射关系,补全主机名与IP地址的映射关系。 (2)从datanode主机ping master节点的主机名(注意也是节点的主机名),如果ping不通,原因可能是datenode节点的/etc/hosts 未配置主机名与IP地址的映射关系,补全主机名与IP地址的映射关系。 (3)查看各机器节点的防火墙是否关闭(或者设置防火墙开启,但对我们的指定端口开放,最好是关闭防火墙)
hankleo
2020/09/17
2.6K0
framework not found -fno-arc编译错误
由于我是刚接手的代码  然后我拿来运行根本就是运行不了的  然后需要在linker 那边删除点东西就可以了。 把下边的两个删除就可以了 关于other linker flags 的介绍 请参考http://blog.csdn.net/meegomeego/article/details/19343423
用户1219438
2018/02/01
5430
framework not found -fno-arc编译错误
控制器到视图的传值方式
(3)TempData        TempData实际上保存在Session中,控制器每次执行请求时都会从Session中获取TempData数据并删除该Session。TempData数据只能在控制器中传递一次,其中的每个元素也只能被访问一次,访问之后会被自动删除。
wfaceboss
2019/04/08
1.3K0
Typecho评论时可能出现的错误
根据URL得知应该是在发评论的时候出现的错误。很奇怪,因为很久之前这位博友jiuki's blog也给我反馈过一次。说明这问题不是偶然出现的,所以必须要解决才行。
Melody132
2020/03/13
1.5K0
【说站】python列表如何传递到线程?
python列表如何传递到线程? 说明 1、所有线程在一个过程中共享全局变量,便于在多个线程之间共享数据。 2、线程是对全局变量的随意遂改可能导致多线程之间的混乱(即线程不安全)。 实例 import time from threading import Thread     def work1(nums):     nums.append(44)     print("----in work1---",nums)     def work2(nums):     #延时一会,保证t1线程中的事情做完
很酷的站长
2022/11/24
5150
【说站】python列表如何传递到线程?
使用Androidkiller或APKIDE编译APK文件时出现libpng error: Not a PNG file的错误
>W: libpng error: Not a PNG file >W: ERROR: Failure processing PNG image D:\xin\AndroidKiller_v1.3.12018\projects\CFF_100\Project\res\mipmap-xxhdpi-v4\ic_launcher.png
全栈程序员站长
2022/11/17
4.4K0
使用Androidkiller或APKIDE编译APK文件时出现libpng error: Not a PNG file的错误
JAVA常用框架及漏洞[通俗易懂]
1. MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情:
全栈程序员站长
2022/07/18
3.5K0
点击加载更多

相似问题

如果存储过程在执行过程中失败,则不执行存储过程

140

创建一个存储过程,该存储过程使用(如果不是)来决定新列中的内容

10

运行存储过程是否需要DbSet?

117

如果从VBA执行存储过程,则不返回数据

13

如果变量为空,则不过滤的存储过程

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文