August 29th, 2014
In Technology
No Comments
If you enjoy this article, see the other most popular articles
If you enjoy this article, see the other most popular articles
If you enjoy this article, see the other most popular articles
The 5 types of dependency injection in Clojure
(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: lawrence@krubner.com, or follow me on Twitter.
Globally Shared
This is often the first way developers think to share data across an application: simply throw it in a def in a namespace and allow any function that needs it to reference it from there.
….It has the advantage of being simple to implement. The disadvantages are numerous and Dependency Injection was originally developed to overcome the shortcoming of globally shared data. Among other things, putting the context in a globally shared data structure will make testing and moving across environment much more cumbersome.
Binding
The next thing people will often try is using the Clojure binding form
This seems to overcome the global shared problem as now a function can access its copy of the form. However, Be Mindful of Clojure’s binding. This is an excellent article which describes some of the perils of using the binding form. It specifically mentions crossing thread boundaries and problem involving lazy sequences. While your context most likely won’t be lazy, it will almost certainly be crossing thread boundaries making the use of binding possibly troublesome.
Function Argument
The first example of lexical scoping is simply passing the context into each function that wants it as an argument.
There is a lot to say for this method and will be the first choice of dependency injection in Clojure. In a majority of cases, this method will serve nicely and makes for nice clean code. However, there is at least one drawback that a simple example does not reveal. The context ends up getting passed to functions that do not use it directly, but just pass it on to functions which they in turn call. If you think of a large project, there may be hundreds of functions all passing around the context just so it can make it way to the bottom layer of code which interacts with the resources. It might be my OO upbringing but this feels like exposing implementation details just as leaky abstraction does in Java.
Closing over the Context
Another method would be closing over the context using let and letfn.
Reader Monad
Monads often get a bad wrap, but for good reason. They are a bit hard to grasp. The examples and tutorials often describe what they are but not what to do with them.Fortunately I found a good example in the presentation “Monads in Clojure” by Leonardo Borgess.
Post external references
- 1
http://software-ninja-ninja.blogspot.co.il/2014/04/5-faces-of-dependency-injection-in.html
February 8, 2022 9:33 am
From Michael S on How I recovered from Lyme Disease: I fasted for two weeks, no food, just water
"Did you have Bartonella, too? Seems it uses autogenesis..."