Dependency Injection is a concept that I’ve been working with since I started blowing apart my initial tic-tac-toe game. Mike first introduced it to me when I was building my own mocks way back in March. I’d been using it throughout my code these past couple of months but what it really just clicked for me again during my review these past couple of days.

Here’s a quick example of how I could and could not using dependency injection, then I’ll explain what it is:

require 'board'

class Game
attr_accesor :ui, :board
def initialize(ui)
@ui = ui
@board = Board.new(3)
end
end

In this example I have a Game class, which I’m considering the high-level module, meaning that it’s the most important class in all of my tic-tac-toe code. That makes sense, I mean it’s the game, right?

My Board and my UI (user interface) are both lower level-modules. Maybe I want to switch up the type of board or use a different UI, and the Game should be able to handle that. It shouldn’t be ‘dependent’ on the lower level modules. If the Game were indeed dependent on the UI and the Board it would be a violation of the Dependency-Inversion Principle, which states that higher-level modules should never depend on lower level modules.

In the example code above I am both obeying and breaking the Dependency-Inversion Principle. With my UI class I’m getting around breaking the principle by delegating the decision of the UI to an injector, which in the case of my command line UI is a simple ruby script to start the game:

ui = CommandLineInterface.new
game = Game.new(ui)
game.play

This script “injects” the Game’s dependency on the UI, which allows me to decide at run-time what UI I want to use, and I can swap it out at any time. When it comes to testing this allows me to substitute a mock UI so that I focus on just testing my Game class.

However, I mentioned that I’m also violating the Dependency-Inversion Principle in the first example code, and that would be with my Board class. The Game class instantiates a board during initialization and then sets its own the @board attribute. This is a hard-coded dependency that I should definitely remove, and fortunately one of my other user stories led me to a possible solution.

The story was to allow my user to decide what size board they wanted to play on. This meant that the Game would no longer instantiate a 3x3 board right off the bat, but instead would be told what kind of board to instantiate.

I still do have one dependency I’m working on this weekend and I’d mentioned a couple of posts ago. The play script inside my Game class is set up for the call-and-response of the command line interface, which makes it dependent on that type of interface. The challenge is to remove that dependency and create some sort of play loop that can be wired up to any interface: the command line, limelight or a web app.

If you’re looking for some more reading on Dependency Injection, the Wikipedia article is pretty straightforward.