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

First Post!

sashaafm

sashaafm

Hey @kostonstyle could you provide a more practical example of what you want to do? Two things you may be interested in are:

  1. Module module, which has functions like concat which let you dynamically build module namespaces.

  2. The Kernel.apply/3 function which let’s yous dynamically call function passing their module and function name as an atom

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.

Last Post!

svarlet

svarlet

It makes perfect sense to me, however I now wonder if I should keep using behaviours for this purpose. This looks nicer and more reliable. What’s the rule of thumb here @michalmuskala ?

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

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 records...
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
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
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...
274 42716 114
New

We're in Beta

About us Mission Statement