MinDI

MinDI is Minimalist Dependency Injection for Ruby. It is inspired by Jamis Buck’s Needle (needle.rubyforge.org) and Jim Weirich’s article on DI in Ruby (onestepback.org/index.cgi/Tech/Ruby/DependencyInjectionInRuby.rdoc).

MinDI is minimalist in that it attempts to map concepts of DI into basic ruby constructs, rather than into a layer of specialized constructs. In particular, classes and modules function as containers and registries, and methods and method definitions function as service points and services. There are some inherent advantages and disadvantages to this approach, discussed below.

MinDI builds on this minimal DI container by adding the InjectableContainer concept, which is a kind of DI available only in dynamic languages: through the magic of method_missing, a service may invoke other services without having explicit setter or constructor references to those services.

Synopsis

Using the BasicContainer module for constructor injection:

require 'mindi'

class SimpleContainer
  include MinDI::BasicContainer

  greeting { "Hello, world\n" }

  point_at { |x,y| [x,y] }

  stuff { [greeting, point_at(100,200)] }
end

cont = SimpleContainer.new

p cont.stuff   # ==> ["Hello, world\n", [100, 200]]

Using the InjectableContainer module for “dynamic” or “fallback” injection, using method_missing:

require 'mindi'

class Transformer
  def transform string
    string.gsub(pattern, &replacement)
  end
end

class TransformerContainer
  include MinDI::InjectableContainer

  pattern     { /foo/ }
  replacement { proc {|match| match.upcase } }
  transformer { Transformer.new }
  transform   { |str| transformer.transform(str) }
end

cont = TransformerContainer.new
s1 = cont.transform("fo foo fee")
s2 = cont.transform("fo foo fee")
p s1              # ==> "fo FOO fee"
p s1.equal?(s2)   # ==> true

Note that the Transformer class is written without explicitly linking up to services (either in initialize or in setters). It just assumes that the services will be defined in the container.

Note also that the transform service is a multiton service, and (like singleton services) it caches its value for each argument.

Advantages

Disadvantages

Notes

Bugs

rather than by putting them in the private section of the class def.

with no argument list will be treated as a multikey_multiton rather than as a singleton. The behavior will be the same, though.

Todo

Legal and Contact Information

Copyright © 2004-2014 Joel VanderWerf, vjoel@users.sourceforge.net.

License is BSD. See COPYING.