Прежде всего вы должны знать, что Elixir будет разрешать файлы конфигурации во время компиляции, что означает, что System.get_env
будет оцениваться при компиляции вашего приложения. В скомпилированном коде значения будут фиксированными.
Команда Elixir работает над упрощением этого процесса, но на данный момент предложенный способ обойти это - отложить чтение переменных среды до запуска вашего приложения.
Обычно это можно сделать в модуле приложения перед запуском дочерних элементов, вызвав Application.put_env/3-4
и введя значения, прочитанные из System.get_env
.
Некоторые библиотеки, такие как Ecto, также предоставляют обратные вызовы init
, которые позволяют подключаться к процессу загрузки для динамической настройки. Смотри https://hexdocs.pm/ecto/Ecto.Repo.html#module-urls
Тогда это также место, где можно избавиться от дублирования. В конце концов, конфигурация - это просто код Elixir, и вы можете просто установить значения, основанные на других, как и следовало ожидать:
defmodule Project.Application do
use Application
def start(_type, _args) do
Application.put_env :project, authentication: [
redirect_uri: "#{Project.Endpoint.static_url()}/oauth/callback",
...
]
children = [
Project.Repo,
ProjectWeb.Endpoint,
...
]
opts = [strategy: :one_for_one, name: Project.Supervisor]
Supervisor.start_link(children, opts)
end
end
Вы также можете смешивать и сочетать как конфигурационный файл, так и Application.put_env
, но тогда вам нужно позаботиться о слиянии значений самостоятельно.