Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the right metaphor for a dependency injection library?

I'm the author of a small C++ library that implements dependency injection (I think someone would call it "IoC container").

I've always thought that finding a good metaphor for a library can help in many ways:

  • it simplifies the use of the library
  • it helps the library's author to find the right abstractions
  • it's a guide to check the soundness of the design
  • it's a way to find meaningful names for the classes
  • and so on...

Now, in my library, I used the device/plug metaphor: your classes are "devices", their dependencies are "plugs", and you can connect a plug in another device. This is a code example:

REGISTERED_CLASS( Foo ), public Device
{
...
private:
    Plug< Bar > bar;
...
};
...
catalog.Create( "myFoo", "Foo" );
catalog.Create( "myBar", "Bar" );
...
catalog[ "myFoo" ].Plug( "bar" ).Into( catalog[ "myBar" ] );     // this means myFoo.bar = myBar

Well, I'm not quite satisfied by this metaphor, because:

  • in real world, you insert plugs into sockets, so the source class should have a plug and the destination class a socket, but in the "code world" I have a pointer of a class pointing to another class;
  • my metaphor doesn't work very well when you have an association with cardinality > 1. I tried with a MultiplePlug< T > (it's basically a std::list< Plug< T > >), but it does not sounds good: what is a "multipleplug" in the real world?

Here you can find my library. Do you have any suggestion for a metaphor that fits better my code?

(Still, if you should have any other good suggestions about the library, they'll be welcome!)

Thank you very much.

Note: I know there is another question with subject "What's a good metaphor for Dependency Injection", but this is not a duplicate of it.

Edit: This is a discussion on the subject in a comment of a famous blog post.

Edit2: Finally, I decided to change the syntax to this nicer and simpler syntax:

// explicit catalog
use( myCatalog["myBar"] ).as( "bar" ).of( myCatalog["myFoo"] );

// implicit catalog:
within( myCatalog )
{
    use( "myBar" ).as( "bar" ).of( "myFoo" );
    ...
}
like image 330
Daniele Pallastrelli Avatar asked Aug 02 '12 16:08

Daniele Pallastrelli


1 Answers

I assume this is for the configuration phase. If you insist on the the Plug and Into terminology:

// this means myFoo.bar = myBar
catalog[ "myFoo" ].Into( "bar" ).Plug( catalog[ "myBar" ] );

where Plug is used as a verb i.e. "to plug". If you creating a fluent interface try to formulate meaningful sentences. If I wanted to configure several dependencies of "myFoo" then I'd be quite happy to write:

catalog[ "myFoo" ].
    .Into( "bar").Plug( "myBar" ) 
    .Into( "some_other_member" ).Plug( "that_other_instance" );

What's a bit unusual is that, normally, when doing configuration you are dealing with types not with instances...

like image 169
Paul Michalik Avatar answered Oct 17 '22 00:10

Paul Michalik