Dependency injection and Reader Monad
Tags: programming, oop, functional, design
Published: 2018-01-05 16:38:22

---
title: Dependency injection and Reader Monad
published: true
description: 
tags: programming, oop, fp, design
---

If you are reading this article you are probably already familiar with dependency injection (DI for short) and its implications. In a nutshell, 
DI suggests that object dependencies should be injected as parameters instead of hard coding them:

```java
// Constructor creates the dependency
class A {
  private final B b; 
  A() {
    b = new B();
  }
}
// Versus the caller supplies the dependency of the class, 
// that's DI in action
class A {
  private final B b; 
  A(B b) {
    this.b = b;
  }
}

```


Only recently I found out that it’s not the only way to dynamically inject dependencies. Another option comes from the functional world and it's called reader monad.
The reader monad let us bound values to functions without the need to pass the values around. One of the usage indeed is to postpone the injection of some data until we know the value it is going to assume.
Hopefully it is going to be more clear after reading the article.
In this article I won't (and can't) fully describe what a Monad is, but it's enough to know that a Monad is a parametrized type which wraps a value and allow to perform operations on it without unwrapping it. (Apologies to the Functional Programming Gods for the definition).
If you, like myself, need to associate the concept with something you already know, you might think about the Optional type in Java or the Either type of Scala:
```java
    public static void main(String[] args) {
        System.out.println(friendsOf("Mickey"));
    }


    public static long friendsOf(String name) {
        // The optional might be empty or might contain the character we are 
        // looking for
        return getCharacterByName(name)
                .map((mickey) -> mickey.friends().count())
                .orElse(0L);
    }
```

`Warning: I am a newbie in functional programming! I am on quest to build a mental knob that let me switch between OOP and FP based on what I need.`

Let’s come back to the main topic, dependency injection and reader monad.
Both can be used to inject dependencies thus both can be used to create more testable, predictable and reusable code. So which one should we use?

Quite a few times, after using DI as usual to supply dependencies to objects I realized there was something wrong with the API of those objects. 
Generally speaking when using dependency injection it might happen that you need some object in a downstream call and this object need to be passed down until it reaches the downstream call.
This is pretty much unavoidable when you have a long lived object (say A) which depends on a short lived object (say B) which gets created based on some parameters we get at the root of the object graph. For example the long lived object might be something that we create only once when the application starts, while the short lived object gets created at runtime based on the user input. 
![sample-object-graph](https://thepracticaldev.s3.amazonaws.com/i/vxrkm1diokqxn5komu7z.png)
When we have a long chain of calls between the point in which B gets created and the one in which B is used, then we are basically passing around B to methods which are not going to use it. That's interface pollution.

One solution could be to make the long lived object, a short lived one by reinstating it along with its dependency. This is not always desirable, because for example the object is expensive to create or is part of a object graph which gets created when the application starts (a graph of singleton, the good singleton not he the bad one :) ). 

##Example
This is a super simple example, just to show the point. All the code used in the article are in [github.com/napicella/js-reader-monad](https://github.com/napicella/js-reader-monad).
Let's suppose we have a Controller which depends on some 'Service'. 
The Service, in turns depends on another service. For sake of simplicity, let's imagine the following chain of calls:
Controller -> Service 1-> Service 2 -> Service 3.
Service 3 performs some computations using an Object which needs to be recreated based on the input received in the controller.
Here we have the sequence diagram:

![sequence diagram](https://thepracticaldev.s3.amazonaws.com/i/3ihm1mluj9tznyzgiwxe.jpg)

The controller creates 'obj' based on the parameters received and passes it down. Service 1 calls Service2.get and add '1' to the result. Similarly Service2 calls Service3.get and add '2' to the result. Finally Service3 uses 'obj' and return the result.


This is the sample code in javascript:
```javascript
/**
 * create a simple object (short lived object in our example)
 */
function createObj(param1, param2) {
  return {
    val1 : param1,
    val2 : param2
  }
}

/**
 * Three long lived objects
 */
function Service1(otherService) {
  return {
    get : (obj) =>  {
      return otherService.get(obj) + 1;
    }
  }
}

function Service2(otherService) {
  return {
    get : (obj) =>  {
      return otherService.get(obj) + 2;
    }
  }
}

function Service3() {
  return {
    get : (obj) => doSomethingWith(obj)
  }
}

function doSomethingWith(someObj) {
  return someObj.val1 + someObj.val2;
}

/**
 * Simple Controller which uses a service to perform some computation
 */
function Controller(service) {
  return {
    someOp : function(param1, param2) {
      // Create an object based on some args recevied from the Controller and
      // pass the object to the service.
      // We could otherwise pass the params to service.
      //
      // Both solutions causes some sort of interface pollution because
      // the obj is only used in Service3
      var obj = createObj(param1, param2);
      return service.get(obj);
    }
  }
}

/**
 * Wire the object graph
 */
function Configuration() {
  return Controller(Service1(Service2(Service3())));
}


var controller = Configuration();
console.log(controller.someOp(10, 20));

```

The code shows how the interface of the three services need to have obj as parameter even thought the parameter is only required for some computation in Service 3. The three services are long lived object created in a Configuration, while obj gets created in the controller based on the parameters received.


Another solution is to use the monad reader.
The idea is to abstract the computation in a monad, which can be used when we know the value that must be used as input to the computation.
In our case, this means that the computation done by the three services is going to be wrapped in a Reader. 
Service3 returns a Reader , Service2 map a function on the value encapsulated in the Reader (value yet to be computed) and the same does Service1.

Sample code with the monad:
```javascript
/**
 * Simple Reader Monad
 */
function reader(k) {
    return {
        run: function(e) {
            return k(e);
        },
        bind: function(f) {
            return reader(function(e) {
                return f(k(e)).run(e);
            });
        },
        map: function(f) {
            return reader(function(e) {
                return f(k(e));
            });
        }
    };
}

/**
 * create a simple object (short lived object in our example)
 */
function createObj(param1, param2) {
  return {
    val1 : param1,
    val2 : param2
  }
}

/**
 * Three long lived objects
 */
function Service1(otherService) {
  return {
    get : () =>  {
      return otherService.get().map((val) => val + 1);
    }
  }
}

function Service2(otherService) {
  return {
    get : () =>  {
      return otherService.get().map((val) => val + 2);
    }
  }
}

function Service3() {
  return {
    get : () => reader(doSomethingWith)
  }
}

function doSomethingWith(someObj) {
  return someObj.val1 + someObj.val2;
}

/**
 * Simple Controller which uses a service to perform some computation
 */
function Controller(service) {
  return {
    someOp : function(param1, param2) {
      // Create an object based on some args recevied from the Controller and
      // pass the object to the service.
      // The service returns a Reader, that we use to inject the object.
      // Thus we do not need to pass the object dowstream.
      var obj = createObj(param1, param2);
      return service.get().run(obj);
    }
  }
}

/**
 * Wire the object graph
 */
function Configuration() {
  return Controller(Service1(Service2(Service3())));
}


var controller = Configuration();
console.log(controller.someOp(10, 20));

```
Here we go, no more obj in the API of the services.

## Conclusions
Hope you find the article useful. 
Any feedback would be greatly appreciated! 


----------------------------------------
Notes
1 - [reader in javascript](https://earldouglas.com/posts/javascript-reader.html)