In a blog
entry, Jamis Buck points out that Needle (a dependency injection framework
based on some of my random
thoughts) is a superset of the Service Locator pattern.
This is true in general. Both the DI and SL patterns provide containers
that you pull objects out of. However, the essential difference between
them is that your application code is aware of the Service Locator pattern,
but Dependency Injection is invisible to the app.
So, if you take your DI container and pass it to a constructor, you are
really using the DI container in a Service Locator manner. The key question
to ask is: If you were to change the interface to the DI container, does
your app need to change as well.
Someone else asked me how to decide between DI and SL, or just rolling your
own. My answer is to look at the amount of pain you suffer on configuring
your the modules of your system. Ruby is flexible enough so that most
projects can get by without either DI or SL. When it begins to get
cumbersome managing different configurations by hand, it is fairly painless
to switch to lightweight DI container such as Needle.
By "configuring your modules", I don’t mean supplying
configuration data to your program, but deciding what modules should be
selected. For example, while testing you might want to use a mock database
layer instead of the real thing.