kostonstyle

kostonstyle

How to use dependency injection pattern in Elixir?

Hi all

I want to make my codes scalable and decide to use dependency injection pattern.

How to use the concept of dependency injection in elixir?

THanks

Most Liked

michalmuskala

michalmuskala

Just to follow up, I’ll give here the same example for this I gave in Slack.

We can define a protocol for our use case - e.g. a repository of users:

defprotocol UserRepository do
  def get(database, id)
end

And then we can define two implementations - one based on a real database and one based on a simple in-memory ETS store:

defmodule Database do
  defstruct [:ecto_repo]

  def new(repo), do: %__MODULE__{ecto_repo: repo}
end

defmodule EtsDatabse do
  defstruct [:table]

  def new(), do: %__MODULE__{table: :ets.new(__MODULE__, [:set, :public])}
end

We can then implement the protocol for those data structures

defimpl UserRepository, for: Database do
  def get(%{ecto_repo: repo}, id) do
    repo.get(User, id)
  end
end

defimpl UserRepository, for; EtsDatabase do
 def get(%{table: table}, id) do
  # assuming {{User, id}, struct} tuples in ets table
  :ets.lookup_element(table, {User, id}, 2)
 end
end

That’s a simple sketch of a protocol-based dependency injection.

mkunikow

mkunikow

Dependency injection is bad pattern used in OO languages to overcome weakness of these languages.
DI frameworks are very dangerous (they do many things under which you don’t have control of)
For this reason I will never use Angular :smiley:
In Java the example of DI is Spring Framework

Dependencies are not good, they are bad! They should be things that we try to avoid wherever possible.
https://dzone.com/articles/dependency-injection-makes

Functional languages don’t need DI.
In functional languages you just compose functions.
For testing you just mock function like GitHub - jjh42/mock: Mocking library for Elixir language

Korbin73

Korbin73

Generally speaking, this question comes up a lot when people are coming from OO languages. @mkunikow makes a valid point that you don’t need it. The solution is fairly simple especially when it comes to testing. If you take the following steps, you won’t need to mock your functions that are touching the outside world.

  1. Keep your impure functions separate from your pure functions. If you have a function that touches a database, calls a webservice, gets the date, etc. Or anything that touches the outside world it should be put in a separate module/function and there should be only one place in your program where it’s called and that data gets passed to your pure functions.

  2. Your unit test will only need the stubbed data that would have come from an impure function like the data that would come from a webservice or a database.

The only time mocking is necessary is when you are calling impure functions from pure functions and they are intertwined (this is true even in OO languages). However, if you keep your impure functions separate from your pure functions then there is no need to have DI or a mocking framework when unit testing.

JEG2

JEG2

Author of Designing Elixir Systems with OTP

If it calls an impure function, it can’t be a pure function. :smile:

mkunikow

mkunikow

Article - example in F#

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement