logo

Wallaroo

C++ Dependency Injection

5 Minutes Tour (for the impatients)

If you're the TL;DR kind, you can read only this page.

Download wallaroo here.

If your compiler does not support C++11, download boost libraries.

Your classes should derive from wallaroo::Part and be registered in the implementation file with the macro WALLAROO_REGISTER. E.g.:

// car.h
#include "wallaroo/registered.h"

using namespace wallaroo;

class Car : public Part
{
public:
    Car( const string& color );
    // other methods declaration here
    ...
};
// car.cpp
WALLAROO_REGISTER( Car, string )

Car::Car( const string& color )
{
...
}

// other methods definition here
...

If your class depends on other objects, you must add wallaroo::Collaborators to it:

class Car : public Part
{
    ...
private:
    Collaborator< Engine > engine; // one instance of Engine
    Collaborator< AirConditioning, optional > airConditioning; // zero or one instance of airConditioning
    Collaborator< Airbag, collection > airbags; // an unspecified number of airbags (std::vector by default)
    Collaborator< Speaker, collection, std::list > speakers; // an unspecified number of speaker in a std::list
    Collaborator< Seat, bounded_collection< 2, 6 > > seats; // from 2 to 6 instances of seats
    ...
};

and gives them names:

Car::Car :
    engine( "engine", RegistrationToken() ),
    airConditioning( "airConditioning", RegistrationToken() ),
    airbags( "airbags", RegistrationToken() ),
    speakers( "speakers", RegistrationToken() ),
    seats( "seats", RegistrationToken() )
{
    ...
}

You can create instances of your registered classes and store them inside a catalog:

#include "wallaroo/catalog.h"

using namespace wallaroo;

...
Catalog catalog; // this is the container of your objects

// populate the catalog with some objects:
catalog.Create( "ferrari_f430", "Car", string( "red" ) );
catalog.Create( "maserati_granturismo", "Car", string( "black" ) );
catalog.Create( "frontLeftSeat", "Seat" );
catalog.Create( "frontRightSeat", "Seat" );
...

You can link together your objects in this way:

Catalog myCatalog;
...
wallaroo_within( myCatalog )
{
    use( "f136e" ).as( "engine" ).of( "ferrari_f430" );
    use( "m139p" ).as( "engine" ).of( "maserati_granturismo" );
}

this is equivalent to:

Catalog myCatalog;
...
use( myCatalog[ "f136e" ] ).as( "engine" ).of( myCatalog[ "ferrari_f430" ] );
use( myCatalog[ "m139p" ] ).as( "engine" ).of( myCatalog[ "maserati_granturismo" ] );

the latter code is useful when your objects are stored in multiple catalogs.

To check whether the wiring satisfies the constraints, you can use Catalog::IsWiringOk() (returns a bool) or Catalog::CheckWiring() (throws an exception).

Finally, you can get a pointer to an object by using the operator [] of Catalog:

shared_ptr< Car > maserati = catalog[ "maserati_granturismo" ];

If you want, you can load the objects and/or the wiring from xml or json configuration files, by using XmlConfiguration and JsonConfiguration:

Catalog catalog;
XmlConfiguration file( "wiring.xml" );
file.Fill( catalog );

You can also define your classes in shared libraries (.dll or .so). In that case, you must use the macro WALLAROO_DYNLIB_REGISTER instead of WALLAROO_REGISTER (every library can contain multiple class definitions and thus multiple WALLAROO_DYNLIB_REGISTER declarations). Before creating instances of a class defined in a shared library, you must load it using the static method Plugin::Load.

You can specify the shared libraries to load in the xml or json configuration files, by using the tag plugin and then read them with the method XmlConfiguration::LoadPlugins or JsonConfiguration::LoadPlugins.

If you want a more detailed tour, you can read the page Getting Started.