返回介绍

依赖注入

发布于 2019-10-12 12:56:38 字数 7800 浏览 2110 评论 0 收藏 0

依赖注入

Dependency Injection is a strong mechanism, which helps us easily manage dependencies of our classes. It is very popular pattern in strongly typed languages like C# and Java.

依赖注入是一个很强大的机制,该机制可以帮助我们轻松管理各个类的依赖。它在类型非常强大的语言如c#Java中是非常流行的模式。

In Node.js it is not such important to use those kind of features, because we already have amazing module loading system and e.g. sharing instance between files is effortless.

在Node.js中,这些功能不是很重要。因为我们已经有了很强大的模块加载系统。比如说,我们可以很轻易地文件之间分享实例。

The module loading system is sufficient for small and medium size applications. When amount of code grows, it is harder and harder to smoothly organize dependencies between layers. It is also less intuitive than DI by constructor.

对于小中型应用程序来说,模块加载系统已经完全够用了。当代码量增加时,组织各个层之间的依赖会变得越来越困难。它还不如构造函数的DI直观。

This is the reason, why Nest has its own DI system.

所以Nest有一套自己的DI系统。

自定义组件

You have already learnt, that it is incredibly easy to add component to chosen module:

你应该已经了解到向选定模块添加组件是非常简单的:

@Module({
    controllers: [ UsersController ],
    components: [ UsersService ]
})

But there is some other scenarios, which Nest allows you to take advantages of.

但是Nest允许你使用其他场景。

When:

  • you want to use specific value. Now, in this module Nest will associate value with UsersService metatype,
  • you want to use test doubles (unit testing).

  • 你想使用具体的值时。在这个模块中,Nest会将值与UsersService元数据相结合。
  • 你想使用测试替身时(单元测试)。

使用值:

const  value = {};
@Module({
    controllers: [ UsersController ],
    components: [ 
        { provide: UsersService, useValue: value }
    ],
})

When:

you want to use chosen, more specific class only in this module.

  • 你想仅在此模块箱使用更精确的选定的类时

使用类:

@Component()
class CustomUsersService {}

@Module({
    controllers: [ UsersController ],
    components: [
        { provide: UsersService, useClass: CustomUsersService }
    ],
})

When:

  • you want to provide a value, which has to be calculated using other components (or custom packages features),
  • you want to provide async value (just return Observable or Promise), e.g. database connection.

  • 你想提供一个必须使用其他组件(或其他自定义包功能)进行计算的值时。
  • 你想提供异步值(只返回Observable或者Promise),例如数据库连接。

    使用 factory:

@Module({
    controllers: [ UsersController ],
    components: [
        ChatService,
        { 
            provide: UsersService, 
            useFactory: (chatService) => {
                return Observable.of('customValue');
            },
            inject: [ ChatService ]
        }
    ],
})

记住:

  • if you want to use components from module, you have to pass them in inject array. Nest will pass instances as a arguments of factory in the same order.

如果你想使用模块内的组件,必须在inject数组中传递组件。Nest会以相同的顺序传递实例作为factory的参数。

When:

  • you want to provide component with a chosen key.

  • 你想提供有选定key的组件时。

自定义 providers

@Module({
    controllers: [ UsersController ],
    components: [
        { provide: 'isProductionMode', useValue: false }
    ],
})

Remember:

记住

  • it is possible to use each types useValue, useClass and useFactory. How to use? To inject custom provided component with chosen key, you have to tell Nest about it, just like that:

可以使用每一个类型的useValueuseClassuseFactory. 如何使用呢?注入带有选定key的自定义提供的组件,并以如下方式告知Nest:

import { Inject } from '@nestjs/common';

@Component()
class SampleComponent {
    constructor(@Inject('isProductionMode') isProductionMode: boolean) {
        console.log(isProductionMode);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文