如何在 Lua 中避免循环依赖而不使用全局变量?

我正在使用 OpenResty,并且我的应用程序设置如下:

app/
   clients/
      photoClient.lua
   init.lua
   auth.lua

假设 photoClient 具有未经身份验证和身份验证的端点(类似于无需登录即可访问的头像端点,但可能存在需要首先登录的私有照片)

因此,在依赖方面,我有:

-- auth.lua

local photoClient = require('app.clients.photoClient')
-- this is used to show avatar on the login page

local auth = {}

auth.isAuthenticated = function ()
   -- logic to check authentication
end

return auth

和客户端

-- photoClient.lua
local auth = require('app.auth')

local photoClient = {}
photoClient.privateEndpoint = function()
   if (!auth.isAuthenticated()) {
       ngx.exit(403)
   }
   ...
end

photoClient.getAvator = function() {
   -- this is a public method used by auth
}

return photoClient

这给我带来了循环依赖问题。我已经在其他 SO 帖子上看到过,可以使用全局变量,即执行 photoClient = photoClient or require('app.clients.photoClient'),但我不想使用全局变量,并且希望保持每个模块自身的范围。

我该怎么做?

点赞
用户834045
用户834045

在 LuaFlare 文档中找到解决方案,由 Kate Adams 提供:在每个文件的 return your_module 之前添加 package.loaded[...] = your_module,即:

-- auth.lua
local auth = {}
package.loaded[...] = auth

local photoClient = require('app.clients.photoClient')

...

return auth

-- photoClient.lua
local photoClient = {}
package.loaded[...] = photoClient

local auth = require('app.auth')

...

return photoClient

问题已经被解决。这里是链接,供有兴趣的读者参考。

2019-02-27 06:21:36
用户79125
用户79125

有两个主要解决方案:

分割

将认证拆分成两个模块来处理不同的方面:一个用于通用逻辑的认证模块,可能会被photoClient使用,一个是登录页面的登录模块。

这个解决方案可以防止在需要使用认证的其他情况下出现同样的问题。

注入

在拥有这两个模块的父级代码(init.lua)中,将一个模块注入到另一个模块中(调用传递模块的函数)。

2022-03-10 18:44:13