0

In typical first example about using the reader monad for dependency injection we have:

this like the classic https://github.com/hermannhueck/composing-functions/blob/master/src/main/scala/demo/Demo08bDbReader.scala

Generally at the core of it is the idea of returning a function that takes as parameter the very thing we want to inject e.g.

trait UserService {
  def getUserbyId(id: String): UserRepo => User
}

I have seen several baby example here and there and they all work proper for the purpose of explaining the main idea.

However i am having a hard time translating that for a real world example where you actually have a Repo that actually connect to a DB.

Indeed, in that scenario, the Account Repo itself depend on something else which is either a DB Connection or an Emvconfig from which the DB connection is created.

This also means that every method of the UserRepo will depend on that DB connection or EnvConfig. If a constructor injection is not used for that repo, then all the methods of the UserRepo will need it too which can escalate back to to whatever Service that call the UserRepo.

Am I missing something here ? I must be otherwise i do not understand the all buzz around it.

Can someone explain what i am missing here ?

MaatDeamon
  • 9,532
  • 9
  • 60
  • 127
  • **Reader** being explained as a way of managing dependency injection is actually _(IMHO)_ on of the worst errors most tutorials do. **Reader** is good as a cool way of composing functions and **ReaderT** or **Kleisli** is a very powerful abstraction. But, but, but, not for dependency injection of a whole application. The best technique for that IMHO is: using interfaces for modelling dependencies, factory contrcutors in the companion objects for creating them, and injecting your dependencies manually using normal parameters. – Luis Miguel Mejía Suárez Dec 04 '20 at 19:32
  • I understand where you are coming from. Maybe too much purity get in the way of practicality. But as i am readying trough on and on again and playing with gist that i find online. It seems the idea is indeed to stick with "explicicity", so you keep the equational reasoning appraoch. You force for everything to be explicit and nothing hidden. Funny because OOP was striving too much on the opposite direction. There must be some good in there as well. As in focus, on what you need to focus on when you need to focus on it and nothing else .... Anyway keeping on readying .... – MaatDeamon Dec 04 '20 at 20:52
  • Note that encapsulation is good and you can see that in FP libraries, for example, take a look to `Fiber` on **cats-effect**, you can see that the methods on it don't require anything but constructing a Fiber requires `Concurrent`. That is the same technique I use, I keep my interfaces clean and my factories receive the dependencies. Remember the idea of **Scala** was to mix the best of both worlds. – Luis Miguel Mejía Suárez Dec 04 '20 at 21:13
  • Agree with you. I am just not where you are yet. But thanks for the reminder. Will read more critically which I guess comes with experience n time anyway – MaatDeamon Dec 04 '20 at 21:19

0 Answers0