Beyond Java - Bruce Tate [62]
You'd then have most of what you'd need for a basic dependency injection container: configuration, third-party life cycle control, and the ability to loosen the coupling between Speaker and Consumer. With a dependency injection container, you could change implementations of Speaker without changing any code in any of the consumers. You could also inject a test implementation of Speaker without impacting the base code, a critical technique in Java for test-first development. You'd also have a consistent strategy for configuration.
A few things come up right off the bat when you look at dependency injection in Ruby. First, Java's not very good at configuration, but Ruby lets you represent structured data quite well, often with far less invasive syntax than XML. You also can solve many of the coupling problems by changing the definition of a class on the fly. It's easier, for example, to inject those mock objects into hard-to-reach places.
Some developers in Ruby seem to think dependency injection is important and that the idea will have a place in the Ruby mainstream, given time. It should come as no surprise to you that Ruby has an outstanding dependency injection framework called Needles.
Others tend to think that dependency injection should happen in spots, instead of with a single, general-purpose framework. Since it's easy to change a class definition on the fly, you can easily inject the behavior that you need without adding another layer of complexity, across the application. Most of the Ruby programming community seems to be converging on the idea that Ruby's overall dynamic design makes dependency injection unnecessary for all but the most complex applications (see the sidebar, "Jim Weirich, Jamis Buck, and David Heinemeier Hansson, Three Ruby Experts: Does Ruby Need Dependency Injection?").
Jim Weirich, Jamis Buck, and David Heinemeier Hansson, Three Ruby Experts: Does Ruby Need Dependency Injection?
Jamis Buck has been writing Ruby code since late 2001, and has written (among various other things) two Ruby dependency injection containers, Ruby bindings for SQLite and SQLite3, and an SSH client library for Ruby. During the day (and some evenings), he works for 37signals, programming in Ruby and Rails. Jamis lives in Provo, Utah, with his wife and two children.
Does Ruby need dependency injection?
JW: The question should not be if Ruby needs dependency injection, but whether a particular application or framework needs dependency injection. DI is a tool to help you build decoupled programs, but it comes with some conceptual baggage. You start using DI when the pain of coupling outweighs the cost of the additional complexity. In some languages, this pain comes fairly quickly. But in Ruby, the pain is mitigated by the natural tendency for looser coupling in a dynamically typed language, so the benefits of dependency injection occur much later in the cost curve. In addition, there are some very simple techniques to lower the cost of coupling without using a formal dependency injection framework.
And finally, when your application/framework does grow to the point that dependency injection becomes interesting, you will find that a simple (i.e., less than 30 lines of code) dependency injection library will fill most of your needs.
JB: I wrote two very different DI containers for Ruby, about a year or two ago. I pushed them both pretty hard, and I worked hard to educate the Ruby community about DI, but the fact is that I really came to understand this: the dynamic nature of Ruby really does obviate the need for most of what DI does in Java land.
DHH: We actually looked into basing the configuration of services in Rails off Needle, but all the problems I was trying to solve with DI could be solved much more simply. For example, dependency injection makes it easier to inject mocks into hard-to-get places. Consider a payment class that initializes a payment gateway to authorize and charge a credit card. Without DI, it might look like this:
class Payment < ActiveRecord::Base
belongs_to