如何跨配置文件重用 Elixir 配置?

How to reuse Elixir config across config files?

我有以下 mix.exs 文件:

config :my_app, MyApp.Repo,
  username: "postgres",
  password: "postgres",
  hostname: "localhost"

我知道,在下面的同一个文件中,不允许这样做:

config :my_app, :postgres, Application.get_env(:my_app, MyApp.Repo)

因为它 returns nil.

不过,我希望在其他文件中可以使用它,例如runtime.exs,但这也不起作用,还会返回 nil 值。

是否可以在配置文件中调用 Application.get_env/2 来获取另一个文件中的配置集?

使用Config.import_config/1

if File.exists?("config/common.exs"),
  do: import_config("common.exs")

Is it possible to call Application.get_env/2 inside a config file to fetch configuration set in some another?

没有。虽然这在某些情况下在技术上是可行的,但正如 Aleksei 所说,这是不鼓励的。虽然在技术上可能不是 100% 准确,但在读取配置时,您的应用尚不存在。您可以使用 System.get_env/2,但不能使用 Application.get_env/2

但是,您可以从 compile-time 配置中包含 other 配置文件。最常见的变体是包含 config/config.exs 中的 environment-specific 配置文件(即 compile-time 配置):

import Config

# ...

# e.g. include config/dev.exs
import_config "#{config_env()}.exs"

# or include config/extra_config.exs
import_config "extra_config.exs"

您会注意到您不能使用运行时配置文件中的 import_config(即 config/runtime.exs)。尝试在那里使用它会产生错误:

** (RuntimeError) import_config/1 is not enabled for this configuration file.

您可以使用 Code.eval_file/2 来“包含”任何 .exs 文件 -- 文件的内容是 returned元组。

Code.eval_file("config/extra.exs") |> elem(0)

您可以使用此方法将 runtime.exs 中的值与另一个文件的内容混合。请记住,以这种方式评估的文件不应使用 config,它们应该只使用 return 值(地图、列表等),例如

# something.exs
[foo: :bar]
config :myapp, :something, Code.eval_file("config/something.exs") |> elem(0)

值得注意的是,提供给 Code.eval_file/2 的路径应该与您的应用程序的根目录相关。您可以将文件放在 config/ 以外的文件夹中,但如果您使用其他位置,则必须自定义您的应用程序构建以包含 and/or 覆盖文件,以便构建的应用程序可以使用它们(而文件config/ 文件中默认包含在构建中)。