express - InversifyJS:每个 HTTP 请求的依赖实例化

标签 express typescript dependency-injection inversifyjs

我在带有 Express 的项目中使用 Inversify.JS。我想创建一个到 Neo4J 数据库的连接,这个过程有两个对象:

  1. 驱动程序对象 - 可以在整个应用程序中共享并且只创建一次
  2. session对象——每个HTTP请求都应该针对driver创建一个session,其生命周期与http请求的生命周期相同(只要请求结束,连接就被销毁)

如果没有 Insersify.JS,这个问题可以用一个简单的算法解决:

exports.getSession = function (context) { // 'context' is the http request 
  if(context.neo4jSession) {
    return context.neo4jSession;
  }
  else {
    context.neo4jSession = driver.session();
    return context.neo4jSession;
  }
};

(示例:https://github.com/neo4j-examples/neo4j-movies-template/blob/master/api/neo4j/dbUtils.js#L13-L21)

要为驱动程序创建静态依赖项,我可以注入(inject)一个常量:

container.bind<DbDriver>("DbDriver").toConstantValue(new Neo4JDbDriver());

我如何创建一个仅每个请求实例化一次的依赖项并从容器中检索它们?

我怀疑我必须像这样在中间件上调用容器:

this._express.use((request, response, next) => {
    // get the container and create an instance of the Neo4JSession for the request lifecycle
    next();
});

提前致谢。

最佳答案

我看到有两种方法可以解决您的问题。

  1. 使用 inRequestScope() 作为 DbDriver 依赖项。 (自 4.5.0 版本起可用)。如果您对一个 http 请求使用单个组合根,它将起作用。换句话说,对于每个 http 请求,您只调用一次 container.get()
  2. 创建子容器,将其附加到 response.locals._container 并将 DbDriver 注册为单例。

    let appContainer = new Container()
    appContainer.bind(SomeDependencySymbol).to(SomeDependencyImpl);
    
    function injectContainerMiddleware(request, response, next) {
         let requestContainer = appContainer.createChildContainer();   
         requestContainer.bind<DbDriver>("DbDriver").toConstantValue(new Neo4JDbDriver());
         response.locals._container = requestContainer;
         next();
    }
    
    express.use(injectContainerMiddleware); //insert injectContainerMiddleware before any other request handler functions
    

在此示例中,您可以在 injectContainerMiddleware 之后注册的任何请求处理程序/中间件函数中从 response.locals._container 检索 DbDriver,您将获取相同的 DbDriver

实例

这会起作用,但我不确定它的性能如何。此外,我猜你可能需要在 http 请求完成后以某种方式处理 requestContainer(取消绑定(bind)所有依赖项并删除对父容器的引用)。

关于express - InversifyJS:每个 HTTP 请求的依赖实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45378966/

相关文章:

javascript - 使用node.js获取特定的JSON对象

node.js - 在 nodejs 服务器中处理绝对 url

javascript - 在呈现 View 之前从父级设置子组件属性

java - 使用 Guice 的模块化 Java 插件系统

android - 通过 Hilt 在 Fragment 和 Activity 之外进行现场注入(inject)

sql - 更改从 SQL Server 数据库获取的数据值

node.js - 为什么需要 module.exports=router ?

reactjs - 如何在 Material ui Popper 中输入过渡 Prop

typescript - 知道 key 的 Typescript Record 访问的复杂性是什么?

android - 替换正在运行的 roboguice 应用程序中的单例实例