Dependency Injection frameworks in Ruby have been pretty much declared unnecessary. Jamis Buck wrote about this last year in his LEGOs, Play-Doh, and Programming blog post.
The general accepted alternative seems to be using some degree of constructor injection, but simply supplying defaults.
class A
end
class B
def initialize(options={})
@client_impl = options[:client] || A
end
def new_client
@client_impl.new
end
end
This approach is fine by me, but it seems to lack one thing from more traditional setups: a way of substituting implementations at runtime based on some external switch.
For example with a Dependency Injection framework I could do something like this (pesudo-C#):
if (IsServerAvailable)
container.Register<IChatServer>(new CenteralizedChatServer());
else
container.Register<IChatServer>(new DistributedChatServer());
This example just registers a different IChatServer
implementation depending on whether our centeralized server is available.
As we're still just using the constructor in Ruby, we don't have programatic control over the dependencies that are used (unless we specify each one ourselves). The examples Jamis gives seem well suited to making classes more testable, but seem to lack the facilities for substitution.
What my question is, is how do you solve this situation in Ruby? I'm open to any answers, including "you just don't need to do that". I just want to know the Ruby perspective on these matters.