From: Joel VanderWerf Date: 2006-04-30T09:45:23+09:00 Subject: [ANN] MinDI 0.3 http://raa.ruby-lang.org/project/mindi/ This version of MinDI adds a new container type, InjectableContainer, which lets you hook up services via method_missing. See the second example below. I'd be interested if anyone knows the correct term for this kind of DI. It's definitely not setter or constructor injection. (The first example below is constructor injection.) Maybe "fallback injection", or "duck interface injection" ? An excerpt from the intro.txt file: == MinDI MinDI is Minimalist Dependency Injection for Ruby. It is inspired by Jamis Buck's Needle (http://needle.rubyforge.org) and Jim Weirich's article on DI in Ruby (http://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. -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407