使用依赖注入的Node.js应用示例

inb24sb2  于 2023-02-15  发布在  Node.js
关注(0)|答案(3)|浏览(118)

我很喜欢Angular 依赖注入的方式,所以我想在节点中使用类似的模式。有很多模块倾向于DI容器,不容易选择。
有没有在节点中使用DI的真示例子?在这种情况下如何构造应用程序?

2ic8powd

2ic8powd1#

我本来有个很性感的答案是关于考试时嘲笑别人的,然后我又看了你的问题,呃.
整个exports/require机制提供了依赖注入,您可以模拟(或交换)任何需要的模块,只需更改require('module')以指向新模块。
您甚至可以 Package 任何您可能想换掉的、API兼容的库集。例如,如果您在决定从underscore迁移到lodash时快要崩溃,您可以使用以下代码创建一个名为“undredash.js”的模块:

if (process.env.COLD_SWEATS || process.env.SHAKING || process.env.PALPITATIONS) {
    module.exports = exports = require('underscore');
} else {
    module.exports = exports = require('lodash');
}

然后当你需要它的时候,只要require('./underdash'),现在你不必关心你实际使用的是哪个下层的库,可以在切换的时候改变它-- * 只要API是一样的,否则你会有一个糟糕的时间 *。

pkln4tw6

pkln4tw62#

我开发并在生产中使用systemic已经一年了。它是electrician的重写,是为TES(大量node.js用户)开发的。两者都没有angular的DI机制那么神奇。您可能也会喜欢diogenes
这里有一个系统应用程序here的例子。

g0czyy6m

g0czyy6m3#

您可以使用injecute来实现此目的。
下面的例子与typescript相关,但是你可以省略类型,使用普通的javascript。

import { default as Express, Handler } from 'express';
import { ArgumentsKey, Func, DependenciesTypes, DIContainer, IDIContainer } from 'injecute';

// helper that helps to pull services from container
export const useContainerServices =
  <S extends Record<ArgumentsKey, any>>(container: IDIContainer<S>) =>
    <
      Keys extends readonly (keyof S)[],
      RequiredServices extends DependenciesTypes<S, Keys>,
      H extends Func<RequiredServices, Handler>
    >(
      servicesNames: [...Keys],
      handlerCreator: H
    ): Handler => {
      return container.injecute<() => Handler, any, any>(handlerCreator, servicesNames);
    };

// business stuff service
class MyBusinessService {
  constructor(private readonly logger: any) {}

  doBusinessStuff(parameter: string) {
    this.logger.log(parameter);
    return Number(parameter);
  }
}

// root app container
const c = new DIContainer()
  .addInstance("logger", console)
  .addSingleton("businessService", MyBusinessService, ['logger']);

// handler creator bounded to your app container
const useServices = useContainerServices(c);

const app = Express();

// use handler on route
app.use('/api/business/stuff/:id', useServices(
  ["businessService"],
  (service) => (req, res, next) => {
    res.json(service.doBusinessStuff(req.params.id));
  }
));

app.listen(3000)
c.get('logger').log('Listening at port 3000')

相关问题