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 · GitHub

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.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
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
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
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
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
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
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement