This post originated from an RSS feed registered with Ruby Buzz
by Christian Neukirchen.
Original Post: Dissident 0.1 released
Feed Title: chris blogs: Ruby stuff
Feed URL: http://chneukirchen.org/blog/category/ruby.atom
Feed Description: a weblog by christian neukirchen - Ruby stuff
Although it took a bit longer than I thought at first, I’m proud to
announce the first public release of Dissident, a Ruby dependency
injection container written by me.
What does Dissident do?
Dissident tries to make the best of different kinds of dependency
injection:
It is as unobtrusive as Setter Injection (aka Type II), but done
magically. It should feel exactly the same as just using the class
if used properly.
It is as easy as Constructor Injection (aka Type III) with, say,
PicoContainer (or what it would look like in an dynamically typed
language), but not as clumsy if used without DI.
It is lazy, like Getter Injection (aka Type “IV”), and exactly as
nice to use. The laziness also solves the problem of circular
instantiations in a clever way.
Dissident can provide real Constructor Injection too, making the
classes truly independent of Dissident.
Features
Dissident provides per-container “singletons” (multitons, actually, if
you make use of parameterized services), that are not globally unique
and visible everywhere to the program, but only for the scope of the
container used.
Dissident can do easy customization and “forking” of container
implementations using standard Ruby inheritance and overriding. You
can, for example, inherit from your default container to add stubs for
testing.
Dissident provides multitons and multimethods for complete
configurability of your applications. A prototypish instantiation
style exists too.
Dissident includes an extensive test suite and is implemented using
test-driven development.
The Dissident core is just a single and rather short file, ready to be
included in your application. It has no external dependencies.
Example code
An example of using Dissident:
require 'dissident'
class Apple
def peel; end
end
class Peeler
inject :peelable
def start
peelable.peel
end
def stop; end
end
class Juicer
inject :peeler
inject :peelable
end
class MyContainer < Dissident::Container
provide :peeler, Peeler
provide :peelable, Apple
end
Dissident.with MyContainer do
juicer = Juicer.new
end
Warning
This release is meant to be thread-safe, but testing in this area has
not been very extensive. Users of threaded applications beware and
please report bugs.
License
Copyright (C) 2005 Christian Neukirchen
Dissident is available under the same liberal terms as Ruby itself.
But why write a new DI framework at all? There are some prejudices
in the Ruby community with respect to that. People say “they make
things complicated” and “there are more frameworks than users”. Of
course, that may be true—but it shouldn’t be for all of
them. Therefore, I decided to make one that’s not complicated,
because you barely notice using it, one that’s easy to pickup,
because you can learn it in an afternoon and only need to write a
few additional lines of Ruby—no XML or YAML needed, one that
actually helps coding, because else it’s a hobble and therefore no
fun, one that eases testing, because you can mock the services
easily (don’t use a container at all, or simply inject mocks), one
that feels like Ruby, because you should never tangle in bad ports
of Java libraries; in the end, I decided to make one that I
personally like and want to use, because there is no point in making
libraries you don’t use on your own.