Generates a dispatch facade for a vanilla Elixir @behaviour module.
Use this when you want DoubleDown's dispatch machinery for a behaviour
you don't control — a third-party library behaviour, an existing
@behaviour in your codebase, or any module that defines @callback
declarations without using defcallback.
For behaviours you do control, prefer DoubleDown.ContractFacade with
defcallback — it gives you richer features (pre_dispatch transforms,
@doc tag sync, combined contract + facade in one module).
Usage
defmodule MyApp.Todos do
use DoubleDown.BehaviourFacade,
behaviour: MyApp.Todos.Behaviour,
otp_app: :my_app
endThe behaviour module must be compiled in a prior compilation
unit — its .beam file must be on disk before the facade
compiles. In a Mix project, this means the behaviour and facade
must be in separate elixirc_paths directories (e.g. behaviour
in lib/ or an earlier test support directory, facade in a
later one). Combined contract + facade in a single module is
not supported — use DoubleDown.ContractFacade for that.
Options
:behaviour(required) — the vanilla behaviour module to generate a facade for. Must define@callbackdeclarations.:otp_app(required) — the OTP application name for config-based dispatch. Implementations are resolved fromApplication.get_env(otp_app, behaviour)[:impl].:test_dispatch?— same asDoubleDown.ContractFacade. Defaults toMix.env() != :prod.:static_dispatch?— same asDoubleDown.ContractFacade. Defaults toMix.env() == :prod.
Param names
Where @callback declarations use annotated types like
id :: String.t(), the annotation name is used as the facade
function's parameter name. For bare types like String.t(),
parameter names are synthesized as arg1, arg2, etc.
Configuration
# config/config.exs
config :my_app, MyApp.Todos.Behaviour, impl: MyApp.Todos.ImplTesting
setup do
DoubleDown.Testing.set_fn_handler(MyApp.Todos.Behaviour, fn
:get_item, [id] -> {:ok, %{id: id}}
:list_items, [] -> []
end)
:ok
endLimitations vs DoubleDown.ContractFacade
- No
pre_dispatchtransforms - No
@doctag sync from contract to facade - No combined contract + facade in one module
- Param names are synthesized for bare (unannotated) types
- No compile-time spec mismatch warnings
See also
DoubleDown.ContractFacade— dispatch facades fordefcallbackcontracts (richer features, recommended for new code).DoubleDown.DynamicFacade— Mimic-style bytecode interception for any module.