OK. So Ruby has enough dependency-injection/inversion-of-control
libraries as it is, but mine is quite different so I figured I’d post
it. It’s about as simple as dependency-injection can possibly become
and there’s no support for lifecycles, interception, or other framework
stuff. Nor is there any support for parents, children, or other
relatives, so keep it to yourself.
Anyway, here’s the code (as released under Ruby’s license, so go ahead
and use it in whatever manner you see fit):
injector.rb:
···
------------
# contents: Dependency injection made simple.
#
# Copyright © 2005 Nikolai Weibull <nikolai@bitwi.se>
module Injector
Dependencies = {}
def needs(path)
const_set path.sub(%r<.*/>, "").capitalize,
if Dependencies.include? path
Dependencies[path]
else
require path
path.split(%r</>).inject(Object){ |o, e| o = o.const_get(e.capitalize) }
end
end
def self.inject(deps)
deps.each{ |path, value| Dependencies[path] = value }
end
end
Yes, that’s right! All it does is make it easy to substitute the
definitions of classes. But hey, that’s precisely what I wanted (and
needed) for one of my projects. And to be honest, I think that it’s
enough under most circumstances.
An example of how to use it follows:
scanner.rb:
-----------
require 'injector'
class Scanner
extend Injector
needs 'error'
def initialize(io)
raise Error, "can only work with open io-ports" if io.closed?
@io = io
end
⋮
end
error.rb:
---------
class Error < StandardError; end
driver.rb:
----------
require 'scanner'
class Driver
⋮
end
tc_driver.rb:
--------------
require 'test/unit'
require 'injector'
require 'scanner'
class Error < ScriptError; end # Or something more creative, perhaps?
Injector.inject(
'error' => Error
)
class TC_Driver < Test::Unit::TestCase
⋮
end
So the idea is that under normal circumstances, ‘needs’ is just a
circumvention for not using ‘require’ directly, but for trying times the
dependency can be changed to something more suitable.
I’ll probably make a real release of this soon, but I was looking for
some comments first, so please, indulge my interest,
nikolai
--
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}