[ANN] My dependency-injection library

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);}
 
T

Trans

Interesting way to create a DI variation of require. Perhaps you
're on to something. There are some issues though.

1) The class name is tied tightly to the file's path.
2) There is only one global Injector.
3) I'm not sure, but the order in which things occur might
be a problem.

T.
 
N

Nikolai Weibull

Interesting idea, but you are only pushing constants around?

I=E2=80=99d like to think that we=E2=80=99re doing a bit more than that.
Can't we do that easier?
Maybe.

Scanner::Error =3D Error
=20
=20
I really fail to see the advantage of using this over manual require
and dependency setting. :)

Well, the thing is, what do you do when you have a compiler class

class Compiler
=E2=8B=AE
raise Error, =E2=80=A6
=E2=8B=AE
end

that also =E2=80=98needs=E2=80=99 our error class?
I personally would expect a DI framework to at least provide a
singleton instantiation scheme, else it wouldn't make any sense to me
at all.

Well, maybe so, but the idea of my library is that all you really need
is to be able to bind constants to classes. It=E2=80=99s definitely not =
much,
but I found that that was precisely what I was looking for.
Einstein once said "Everything should be made as simple as possible,
but not simpler".

Or something to that effect, yes. (I have yet to find the actual source
of this quotation. Not that I=E2=80=99m doubting that he said it, but I =
am
wondering if he said/wrote it in English or German and if there was some
context to it as well.)

I think anything more simple than Matz-DI is too simple.

Perhaps, but again, all I was looking for is done by my library. I=E2=80=
=99m
certainly not trying to force people to stop using needle or some other
library (e.g., dissident). To me, needle is doing a bit too much and I
seem to have a hard time reading your examples for dissident (how do you
do namespacing in dissident?), so I haven=E2=80=99t given it a chance yet=
,
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);}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top