[ANN] Dissident 0.1, a Ruby dependency injection container

Hello,

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 <http://purl.org/net/chneukirchen&gt;
Dissident is available under the same liberal terms as Ruby itself.

== Where can I get it?

You can get Dissident 0.1 at:

       http://chneukirchen.org/releases/dissident-0.1.0.tar.gz

Alternatively, you can checkout from the development repository with:

    darcs get Index of /repos/dissident/

(Patches using "darcs send" are most welcome.)

For more information on Dissident, please also see
http://rubyurl.com/bPh and http://rubyurl.com/PMc

Quoting from the latter:

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.

Happy hacking and have a nice day,
Christian Neukirchen

ea5772084443719e310f586ff43436e2 dissident-0.1.0.tar.gz

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Very good, congratulations on the release. I'll be taking a look at this.

I must ask the inevitable question: how does Dissident compare/contrast to
Needle and/or other Ruby DI containers?

···

On Tue, September 20, 2005 8:22 am, Christian Neukirchen said:

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.

--
Jason Voegele
"There is an essential core at the center of each man and woman that
remains unaltered no matter how life's externals may be transformed
or recombined. But it's smaller than we think."
    -- Gene Wolfe, The Book of the Long Sun

"Jason Voegele" <jason@jvoegele.com> writes:

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.

Very good, congratulations on the release. I'll be taking a look at this.

Thank you.

I must ask the inevitable question: how does Dissident compare/contrast to
Needle and/or other Ruby DI containers?

Needle was the only DI container I really used before Dissident. It
has far more features and some more advanced concepts (Interceptors,
Logging) than Dissident. However, I noticed that I didn't need most
of them. Dissident is, in the end, a reimplementation of the features
I need of a quite Needle-like framework. If you know Matz-DI, you
could say it's like Matz-DI with all three approaches merged and made
almost transparent. I think it's the transparency that makes
Dissident so convenient.

Some other containers out there, most notably Copland and Seep, are
configured in YAML and XML; one could say they are "too static" to
directly compare to Dissident. To be honest, I did not really look
deeper into these approaches.

I don't know of other libraries for DI in Ruby right now, but I can
tell you that (the Java version of) PicoContainer was quite an
inspiration for Dissident.

Last but not the least, Dissident came to my mind explaining a few
hacks I did to Needle to Jim Weirich, after doing some Lisp hacking.
(Cf. multimethod dispatch and having the current container in a
dynamically-scoped variable.)

···

On Tue, September 20, 2005 8:22 am, Christian Neukirchen said:

Jason Voegele

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

This is a little OT, but every-time dependency injection comes up I go a googling, and I never seem to be able to wrap my head around an explanation of what it is, and what the purpose is. Could someone point me to a good explanation?

Logan Capaldo wrote:

This is a little OT, but every-time dependency injection comes up I go a googling, and I never seem to be able to wrap my head around an explanation of what it is, and what the purpose is. Could someone point me to a good explanation?

Check:
*) Inversion Of Control
*) Inversion of Control Containers and the Dependency Injection pattern

The whole point is about lower coupling, higher cohesion, enhance independence, ease testing in isolation.

Ciao
Giuliano

···

--
If you want to send me an email address should be 'p', then a dot, followed by 'bossi' at 'quinary', another dot and 'com' at last

Piergiuliano Bossi wrote:

Logan Capaldo wrote:

This is a little OT, but every-time dependency injection comes up I go a googling, and I never seem to be able to wrap my head around an explanation of what it is, and what the purpose is. Could someone point me to a good explanation?

Check:
*) Inversion Of Control
*) Inversion of Control Containers and the Dependency Injection pattern

The whole point is about lower coupling, higher cohesion, enhance independence, ease testing in isolation.

Ciao
Giuliano

Ehm, to be precise I'm not advocating the use of an IoC container; on the other side, the principle of dependency injection is an important tool to put in your box.

Giuliano

···

--
If you want to send me an email address should be 'p', then a dot, followed by 'bossi' at 'quinary', another dot and 'com' at last

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:

Logan Capaldo wrote:

This is a little OT, but every-time dependency injection comes up I
go a googling, and I never seem to be able to wrap my head around an
explanation of what it is, and what the purpose is. Could someone
point me to a good explanation?

Check:
*) Inversion Of Control
*) Inversion of Control Containers and the Dependency Injection pattern

The whole point is about lower coupling, higher cohesion, enhance
independence, ease testing in isolation.

Also see OSCON 2005 - Dependency Injection - Cover for a Ruby POV.

···

Giuliano

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Aha, thanks for the ruby example, it kind of cleared up the Java examples.

···

On Sep 21, 2005, at 1:55 PM, Christian Neukirchen wrote:

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:

Logan Capaldo wrote:

This is a little OT, but every-time dependency injection comes up I
go a googling, and I never seem to be able to wrap my head around an
explanation of what it is, and what the purpose is. Could someone
point me to a good explanation?

Check:
*) InversionOfControl
*) Inversion of Control Containers and the Dependency Injection pattern

The whole point is about lower coupling, higher cohesion, enhance
independence, ease testing in isolation.

Also see OSCON 2005 - Dependency Injection - Cover for a Ruby POV.

Giuliano

-- Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:

Piergiuliano Bossi wrote:

Logan Capaldo wrote:

The whole point is about lower coupling, higher cohesion, enhance
independence, ease testing in isolation.

Ehm, to be precise I'm not advocating the use of an IoC container; on
the other side, the principle of dependency injection is an important
tool to put in your box.

Just curious, but you could explain why you do not advocate using IoC
containers?

···

Giuliano

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

In my understanding, Giuliano wasn't advocating against using IoC
frameworks[1] (or more specifically, DI frameworks[2]). He simply
disclaimed himself from advocating a framework or frameworks in
general. He advocates DI as a principle/tool but leaves it at that.

Of course, he may indeed have been advocating against using DI
frameworks, in which case I'll let him go ahead and defend his
position. :slight_smile:

Jacob Fugal

[1] I replaced discussion of "containers" with "frameworks". A
container is an element of one approach to dependency injection. It's
not a necessary element, and even when it is used it may be named
differently (e.g. Coplands "registry"). Also, ad-hoc DI without a
framework may use a form of container. What's being discussed -- ie.
entities such as Copland, Needle, Dissident, Matz-DI and even Java's
PicoContainer (despite the word "Container" in the name) -- are
frameworks.

[2] The confusion about Inversion of Control (IoC) versus Dependency
Injection (DI) is significant. I'd suggest avoiding the term IoC in
favor of DI unless you are specifically talking about an IoC principle
which is independent of DI.

···

On 9/22/05, Christian Neukirchen <chneukirchen@gmail.com> wrote:

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:
> Ehm, to be precise I'm not advocating the use of an IoC container; on
> the other side, the principle of dependency injection is an important
> tool to put in your box.

Just curious, but you could explain why you do not advocate using IoC
containers?

Christian Neukirchen wrote:

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:

Piergiuliano Bossi wrote:

Logan Capaldo wrote:

The whole point is about lower coupling, higher cohesion, enhance
independence, ease testing in isolation.

Ehm, to be precise I'm not advocating the use of an IoC container; on
the other side, the principle of dependency injection is an important
tool to put in your box.

Just curious, but you could explain why you do not advocate using IoC
containers?

Jacob explained it perfectly. FWIW, I like Jim Weirich position too.
The exact need for an IoC container/framework would be less important/frequent if you use a flexible language like ruby and/or you develop with dependency injection in mind.

Ciao
Giuliano

···

--
If you want to send me an email address should be 'p', then a dot, followed by 'bossi' at 'quinary', another dot and 'com' at last

Jacob Fugal wrote:

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:

Ehm, to be precise I'm not advocating the use of an IoC container; on
the other side, the principle of dependency injection is an important
tool to put in your box.

Just curious, but you could explain why you do not advocate using IoC
containers?

In my understanding, Giuliano wasn't advocating against using IoC
frameworks[1] (or more specifically, DI frameworks[2]). He simply
disclaimed himself from advocating a framework or frameworks in
general. He advocates DI as a principle/tool but leaves it at that.

I cannot say it better than you! :slight_smile:
If one day you plan to become a lawyer I may hire you.

Of course, he may indeed have been advocating against using DI
frameworks, in which case I'll let him go ahead and defend his
position. :slight_smile:

Jacob Fugal

[1] I replaced discussion of "containers" with "frameworks". A
container is an element of one approach to dependency injection. It's
not a necessary element, and even when it is used it may be named
differently (e.g. Coplands "registry"). Also, ad-hoc DI without a
framework may use a form of container. What's being discussed -- ie.
entities such as Copland, Needle, Dissident, Matz-DI and even Java's
PicoContainer (despite the word "Container" in the name) -- are
frameworks.

+1

[2] The confusion about Inversion of Control (IoC) versus Dependency
Injection (DI) is significant. I'd suggest avoiding the term IoC in
favor of DI unless you are specifically talking about an IoC principle
which is independent of DI.

+1

Ciao
Giuliano

···

On 9/22/05, Christian Neukirchen <chneukirchen@gmail.com> wrote:

--
If you want to send me an email address should be 'p', then a dot, followed by 'bossi' at 'quinary', another dot and 'com' at last

Jacob Fugal <lukfugl@gmail.com> writes:

Piergiuliano Bossi <p_bossi_AGAINST_SPAM@tiscali.it> writes:
> Ehm, to be precise I'm not advocating the use of an IoC container; on
> the other side, the principle of dependency injection is an important
> tool to put in your box.

Just curious, but you could explain why you do not advocate using IoC
containers?

In my understanding, Giuliano wasn't advocating against using IoC
frameworks[1] (or more specifically, DI frameworks[2]). He simply
disclaimed himself from advocating a framework or frameworks in
general. He advocates DI as a principle/tool but leaves it at that.

I must have misinterpreted him then.

Of course, he may indeed have been advocating against using DI
frameworks, in which case I'll let him go ahead and defend his
position. :slight_smile:

Jacob Fugal

[1] I replaced discussion of "containers" with "frameworks". A
container is an element of one approach to dependency injection. It's
not a necessary element, and even when it is used it may be named
differently (e.g. Coplands "registry"). Also, ad-hoc DI without a
framework may use a form of container. What's being discussed -- ie.
entities such as Copland, Needle, Dissident, Matz-DI and even Java's
PicoContainer (despite the word "Container" in the name) -- are
frameworks.

Yes, you are right. However, I try to avoid calling Dissident a
"framework", because "framework" has a bit of a bad taste for some
people. You could call it a "dependency injection library" if
container is not precise enough.

[2] The confusion about Inversion of Control (IoC) versus Dependency
Injection (DI) is significant. I'd suggest avoiding the term IoC in
favor of DI unless you are specifically talking about an IoC principle
which is independent of DI.

Yes, I was just picking up the term Piergiuliano used.

···

On 9/22/05, Christian Neukirchen <chneukirchen@gmail.com> wrote:

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org