Javascript Dependency Injection with partial functions

Published on 30 October 2012 by @mathiasverraes

My gut reaction when writing Javascript, is to try and mimck patterns and concepts that I’m used to in class-based languages. Turns out Javascript allows you to do a whole bunch of things differently, and, dare I say it, more elegantly. All you have to do is let go of the luggage you bring from languages like Java or PHP.

Say we want to handle some commands. In classical OOP, we’d start by making a CommandHandler, and give it one public method called handle(command). Our method is probably going to have some services it depends on, like a Repository. We inject that into the class’ constructor. (Note that in javascript, passing repository as a parameter will automatically bring it into scope in handle()).

Elsewhere, we create an instance of the CommandHandler – for example when we set up a dependency injection container. And again elsewhere, we call the handle method on our instance.

// CommandHandler Class
var CommandHandler = function(repository) {
  this.handle = function(command) {
    // do stuff with repository and command
  }
}

// Elsewhere, create an instance of the class...
var myCommandHandler = new CommandHandler(repository);

// ...and use it
myCommandHandler.handle(command);

Going class-less

This sort of code is all too familiar, and it’s perfectly valid in Javascript. But a couple of things bug me. First of all there’s the Noun.verb() combo. We’re really only interested in one method: handle. Yet we have to have a class, with an artificial name like CommandHandler, which is just a there to bring us the handle method.

A second quirk of class-based OOP, is that we need to have a class, as well as an instance of that class. I’m not saying there’s anything wrong with that, but after a couple of days diging into Javascript, it feels silly.

So let’s get rid of the class, and keep only the verb, aka the handle() method. That means we now have to pass in the Repository in some other way. We can pass it in as a parameter, but that’s awkward, because then we’d have to have the Repository object available everywhere we want the handle(), but that’s too much internal information for client code to know.

Partial functions to the rescue

Functional programming has a neat little trick that can be applied here. A partial is function that takes another function, and ‘pre-fills’ a number of parameters. It returns a function that only needs the leftover parameters. Here’s a typical example:

var sum = function(a, b) {
  return a + b;
}

var addFiveTo = partial(sum, 5);

sum(5, 10) // returns 15
addFiveTo(10) // returns 15

Partials can easily be used to ‘configure’ a function in a DIC, and the use the pre-configured version of the function in the client code:

var _ = require('lodash'); // Lodash is an API-compatible fork of Underscore.js

// The same as the first example, but as a class-less function
var handle = function(repository, command) {
  // do stuff with repository and command
}

// Elsewhere, inject the repository by creating a partial
var handle = _.partial(handle, repository);

// ...and use it
handle(command);

I’m still playing around with this kind of code, so I haven’t decided yet if this is the approach I’ll be using to replace all single-method classes. In any case, Javascript’s dynamic nature makes it easy to come up with many different ways of doing this.

Comments

Marijn Huizendveld - 2012/10/30

This looks nice. However, what you loose in cruft you also loose in clarity. In the class-based implementation, a new developer can simply look up the class definition to see the dependencies of a certain command handler. It seems to me that with this partial-function approach a new developer has to look at the handler implementation and the DIC to validate what stuff gets injected. Not sure if that’s a trade-off I’d be willing to make.

Mathias Verraes - 2012/10/30

If you’re just writing client code, I don’t think there’s any added complexity. In production code, you’d write something like container.handleCommand(command) instead of container.commandHandler.handle(command). I suppose you could do type hinting in an IDE with annotations like JsDoc or Google Closure Compiler, so that should help reduce the clicking around. But as I said, I’m stilling fooling around, I’m sure I’ll get a better feel for what is practical and what is not.

Follow @mathiasverraes on Twitter.



Upcoming

2017
Topic Event Type Location Date
Modelling Heuristics Workshop @ Domain-Driven Design Europe workshop Amsterdam, NL Feb 1
Conference Domain-Driven Design Europe 2017 organiser Amsterdam, NL Jan 31 - Feb 3
Domain-Driven Design Neos Conference workshop Hamburg, DE Mar 30
Keynote (TBD) Neos Conference keynote Hamburg, DE Mar 31
Older entries...

Blog Atom

2016

2015

2014

2013

2012

2011

Creative Commons License This work by Mathias Verraes is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 License.