我有两个mix
项目 P1 和 P2。
P1 依赖于 ecto 并提供了一个 genserver 接口。它也被添加为 P2 中的依赖项,仅用于访问某些客户端功能。所以 P2 不会尝试启动 P1。它是独立启动的。
问题是 P2 无法编译。mix compile
表示P1.Repo
缺少适配器配置。
我不想在 P2 中包含 P1 的任何 repo 配置。在这些情况下,有什么方法可以使用 P2 内部的 P1 模块提供的功能?
我有两个mix
项目 P1 和 P2。
P1 依赖于 ecto 并提供了一个 genserver 接口。它也被添加为 P2 中的依赖项,仅用于访问某些客户端功能。所以 P2 不会尝试启动 P1。它是独立启动的。
问题是 P2 无法编译。mix compile
表示P1.Repo
缺少适配器配置。
我不想在 P2 中包含 P1 的任何 repo 配置。在这些情况下,有什么方法可以使用 P2 内部的 P1 模块提供的功能?
这是 Ecto 特定的,但您可以在将模块定义为 repo 时提供编译时配置。
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
end
然后,您可以在 repo 的init/2
回调中添加运行时配置。
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
def init(_type, config) do
new_config = Keyword.put(config, :url, System.get_env("DATABASE_URL"))
{:ok, new_config}
end
end
一个更通用的解决方案是提供应用程序配置作为mix.exs
':env
选项的一部分。我相信这只是运行时(如果我错了,请有人纠正我)。
这是mix help compile.app
对此提供的内容。
:env - 应用程序环境的默认值。应用程序环境是配置应用程序最常用的方法之一。有关读取和写入应用程序环境的机制,请参阅应用程序模块。
这是一个使用的例子application/0
。mix.exs
:env
def application do
[extra_applications: [:logger, :crypto],
env: [key: :value],
registered: [MyServer]]
end
如果 P1 是 P2 的依赖项,则 P2 负责配置并且没有什么可以改变它,但是您还有其他几个选项:
使用伞项目伞项目可以通过 P1.Repo 拥有自己的配置。这样你就可以保持 P1 和 P2 配置更干净。
此外,您可以从 P2 使用的 P1 中取出有意义的块并将其移动到 P3。P1 和 P2 都依赖于 P3。