4

In Real World Ocaml Chapter 9 which is about functors :

Dependency injection

Makes the implementations of some components of a system swappable. This is particularly useful when you want to mock up parts of your system for testing and simulation purposes.

But I fail to grasp the idea. I also looked at Wikipedia about DI - but I actually do not catch the relaton with testing and simulation purposes.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
Pierre G.
  • 4,346
  • 1
  • 12
  • 25

2 Answers2

7

Dependency injection is a software engineering technique, whose purpose is to reduce the interdependencies between two subsystems of a program. A very important detail of this technique, is that it involves not two, but three subsystems:

  • a service,
  • a client using a
  • an injector, whose responsibility is to prepare a service for a client.

The latter subsystem, with its responsibility, an often overlooked but crucial detail: this implies that the client knows as little about the service as its public interface, which means that one can easily use a mocked service to test the client.

Assume that we write an application communicating with a key-value store over the network. The key-value store has the following signature:

module type AbstractKeyValueStoreService =
sig
   exception NetworkError
   type t
   val list : t -> string
   val find : t -> string -> string option
   val set : t -> string -> string -> unit
end

If we write our client code as a client parametrise by a module of type AbstractKeyValueStoreService we can test the resilience of our application to network errors when using the set function by just providing a mocked service, without needing to actually create the network error:

module KeyValueStoreServiceFailingOnSet =
struct
  exception NetworkError
  type t = unit
  let list () = [ "a"; "b"]
  let find = function
    | "a" -> Some("x")
    | "b" -> Some("y")
    | _ -> None
  let set _ _ = raise NetworkError
end

If our client is written as functor parametrised by a module of type AbstractKeyValueStoreService it is easy to write tests for this software component, where a mocking service follow a more-or-less complex interaction script with the client.

Using modules as parameters might not be an “earth shaking idea” it is nevertheless important to be aware of how this idea can be used to solve important software engineering problems. This is what the authors of “real world OCaml” seem to do.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Michaël Le Barbier
  • 6,103
  • 5
  • 28
  • 57
0

It seems to me they're just trying to show how the term "dependency injection" can be seen to refer to parameters that are full modules. And that's what OCaml functors are: modules with parameters that are also modules.

This has many uses, not just testing and simulation. But certainly you can use it for those. For example, you can use it to supply a "mock" module during testing, to replace some part of the system that's difficult to reproduce exactly in the test environment.

One way to look at this is that "dependency injection" isn't as interesting or novel as its adherents might want you to think. At least that's what I think personally. Using modules as parameters isn't an earth shaking idea, it's been around for decades in the ML languages. In Angular (at least), this is mixed up with a separate notion, that of having the names of function parameters be semantically meaningful. That (IMHO) is a mistake.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108