Dependency injection 如何为Elixir GenServer进行依赖项注入?
我正在用Elixir构建一个GenServer,假设它是这样一个简单的队列Dependency injection 如何为Elixir GenServer进行依赖项注入?,dependency-injection,elixir,Dependency Injection,Elixir,我正在用Elixir构建一个GenServer,假设它是这样一个简单的队列 defmodule Queue do use GenServer def start_link(name) do GenServer.start_link(__MODULE__, :ok, name: name) end def push(server, msg) do GenServer.call(server, {:subscribe, channel, last_id}) e
defmodule Queue do
use GenServer
def start_link(name) do
GenServer.start_link(__MODULE__, :ok, name: name)
end
def push(server, msg) do
GenServer.call(server, {:subscribe, channel, last_id})
end
def pop(server) do
GenServer.call(server, {:pop, channel, last_id})
end
# handlers here ...
end
{:ok, redis_queue} = Queue.start_link(:RedisQueue, redis_process_pid)
对于这个队列,我希望提供不同的存储后端,如
- PostgreSQL
- 雷迪斯
- 记忆中
- 文件
{:ok, db_queue} = Queue.start_link(:DBQueue, db_process_pid)
而对于redis来说,可能是这样的
defmodule Queue do
use GenServer
def start_link(name) do
GenServer.start_link(__MODULE__, :ok, name: name)
end
def push(server, msg) do
GenServer.call(server, {:subscribe, channel, last_id})
end
def pop(server) do
GenServer.call(server, {:pop, channel, last_id})
end
# handlers here ...
end
{:ok, redis_queue} = Queue.start_link(:RedisQueue, redis_process_pid)
通过这种方式,我可以创建具有不同后端的相同队列服务器。Elixir为GenServer执行依赖项注入的最佳实践是什么 如果只想存储pid,可以使用GenServer状态来存储它。然后可以从
句柄*
回调函数访问它。例如,以下是队列的情况:
defmodule Queue do
use GenServer
def start_link(name, pid) do
GenServer.start_link(__MODULE__, pid, name: name)
end
def init(pid), do: {:ok, pid}
...
end
现在,您可以按照自己的意愿启动它:
{:ok, db_queue} = Queue.start_link(:DBQueue, db_process_pid)
然后在handle.*
回调中,访问上一个参数的状态(在本例中只是一个pid):
def handle_call({:subscribe, channel, last_id}, from, pid) do
# use the pid and the message to construct a reply
reply = ...
{:reply, reply, pid}
end
如果您想存储更多的东西,比如说模块,只需将
pid
随处更改为%{pid:…,module:…}
。任何Erlang术语都可以用作状态。如果只想存储pid,可以使用GenServer状态来存储它。然后可以从句柄*
回调函数访问它。例如,以下是队列的情况:
defmodule Queue do
use GenServer
def start_link(name, pid) do
GenServer.start_link(__MODULE__, pid, name: name)
end
def init(pid), do: {:ok, pid}
...
end
现在,您可以按照自己的意愿启动它:
{:ok, db_queue} = Queue.start_link(:DBQueue, db_process_pid)
然后在handle.*
回调中,访问上一个参数的状态(在本例中只是一个pid):
def handle_call({:subscribe, channel, last_id}, from, pid) do
# use the pid and the message to construct a reply
reply = ...
{:reply, reply, pid}
end
如果您想存储更多的东西,比如说模块,只需将pid
随处更改为%{pid:…,module:…}
。任何Erlang术语都可以用作状态