Dependency Injection in Clojure?

A lot of good advice here but I don’t think the question of Dependency Injection really got addressed directly? DI/IoC in Java and similar languages is mostly about lifting the burden of object construction away from the developer and handing it off to a framework so that objects can depend on each other in various ways and the DI/IoC framework will figure it all out for you.

In Clojure, there really are no objects, so there’s no dependency graph at that level and no DI to perform. Component is the closest you will find – it will feel fairly OO (indeed, that’s one of the criticisms leveled at it) – but its focus is very narrow: to wire together a graph of subsystems within your application that require a lifecycle: some sort of startup initialization and, potentially, some sort of shutdown cleanup.

Aside from Component, the only dependency graph you’ll have to deal with is namespaces themselves and that is very explicit: a namespace will require its dependencies – the namespaces it needs – and those in turn require the namespaces they need and so on. No DI there.

On the question of Java interfaces and polymorphism, the closest you’ll see in Clojure is protocols and records (which provide “classes” that implement the protocols). But in idiomatic Clojure, you only use polymorphism where you really need it – a la carte polymorphism – and you also have the choice of multimethods to offer polymorphism based on multiple dispatch, rather than single dispatch.

But as a general guiding principle, focus on a separation of data and functionality – something that is really the antithesis of Java – and remember that Clojure is built on certain abstractions already: sequence, associative, counted, indexed, etc. Then use additional abstractions and polymorphism “as needed”.

3 Likes