N
Nikolai Weibull
OK. So Ruby has enough dependency-injection/inversion-of-control
libraries as it is, but mine is quite different so I figured I=E2=80=99d =
post
it. It=E2=80=99s about as simple as dependency-injection can possibly be=
come
and there=E2=80=99s no support for lifecycles, interception, or other fra=
mework
stuff. Nor is there any support for parents, children, or other
relatives, so keep it to yourself.
Anyway, here=E2=80=99s the code (as released under Ruby=E2=80=99s license=
, so go ahead
and use it in whatever manner you see fit):
injector.rb:
------------
# contents: Dependency injection made simple.
#
# Copyright =C2=A9 2005 Nikolai Weibull <[email protected]>
module Injector
Dependencies =3D {}
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 =3D o.const_get(e.capi=
talize) }
end
end
def self.inject(deps)
deps.each{ |path, value| Dependencies[path] =3D value }
end
end
Yes, that=E2=80=99s right! All it does is make it easy to substitute the
definitions of classes. But hey, that=E2=80=99s precisely what I wanted =
(and
needed) for one of my projects. And to be honest, I think that it=E2=80=99=
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 =3D io
end
=E2=8B=AE
end
error.rb:
---------
class Error < StandardError; end
driver.rb:
----------
require 'scanner'
class Driver
=E2=8B=AE
end
tc_driver.rb:
--------------
require 'test/unit'
require 'injector'
require 'scanner'
class Error < ScriptError; end # Or something more creative, perhaps?
Injector.inject(
'error' =3D> Error
)
class TC_Driver < Test::Unit::TestCase
=E2=8B=AE
end
So the idea is that under normal circumstances, =E2=80=98needs=E2=80=99 i=
s just a
circumvention for not using =E2=80=98require=E2=80=99 directly, but for t=
rying times the
dependency can be changed to something more suitable.
I=E2=80=99ll probably make a real release of this soon, but I was looking=
for
some comments first, so please, indulge my interest,
nikolai
--=20
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);}
libraries as it is, but mine is quite different so I figured I=E2=80=99d =
post
it. It=E2=80=99s about as simple as dependency-injection can possibly be=
come
and there=E2=80=99s no support for lifecycles, interception, or other fra=
mework
stuff. Nor is there any support for parents, children, or other
relatives, so keep it to yourself.
Anyway, here=E2=80=99s the code (as released under Ruby=E2=80=99s license=
, so go ahead
and use it in whatever manner you see fit):
injector.rb:
------------
# contents: Dependency injection made simple.
#
# Copyright =C2=A9 2005 Nikolai Weibull <[email protected]>
module Injector
Dependencies =3D {}
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 =3D o.const_get(e.capi=
talize) }
end
end
def self.inject(deps)
deps.each{ |path, value| Dependencies[path] =3D value }
end
end
Yes, that=E2=80=99s right! All it does is make it easy to substitute the
definitions of classes. But hey, that=E2=80=99s precisely what I wanted =
(and
needed) for one of my projects. And to be honest, I think that it=E2=80=99=
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 =3D io
end
=E2=8B=AE
end
error.rb:
---------
class Error < StandardError; end
driver.rb:
----------
require 'scanner'
class Driver
=E2=8B=AE
end
tc_driver.rb:
--------------
require 'test/unit'
require 'injector'
require 'scanner'
class Error < ScriptError; end # Or something more creative, perhaps?
Injector.inject(
'error' =3D> Error
)
class TC_Driver < Test::Unit::TestCase
=E2=8B=AE
end
So the idea is that under normal circumstances, =E2=80=98needs=E2=80=99 i=
s just a
circumvention for not using =E2=80=98require=E2=80=99 directly, but for t=
rying times the
dependency can be changed to something more suitable.
I=E2=80=99ll probably make a real release of this soon, but I was looking=
for
some comments first, so please, indulge my interest,
nikolai
--=20
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);}