logo

Wallaroo

C++ Dependency Injection

Attributes

Starting from version 0.6, you can add "attributes" to your objects. Wallaroo attributes are similar to standard C++ class attributes, except their value can be assigned in the configuration file or by using a DSL similar to the one used for wiring.

Wallaroo attributes are the solution to the limit in the numbers of constructor parameters in classes managed by wallaroo. (see this page and discussion on the wiki).

Define attributes in your classes

This is an example of attribute declaration:

// triangle.h

class Triangle : public wallaroo::Part
{
    ...
private:
    const Attribute< unsigned int > base;
    const Attribute< unsigned int > height;
};

In the constructor, you must give a name to your attributes, so that you can name them in the configuration file or in the DSL:

// triangle.cpp

Triangle::Triangle() :
    base( "base", RegistrationToken() ),
    height( "height", RegistrationToken() ),
    ...
{
}

Assign attribute values from code

After you create an object, you can assign a value to its attributes by using this Domain Specific Language:

    set_attribute( "base" ).of( shape_catalog[ "triangle1" ] ).to( 10 );
    set_attribute( "height" ).of( shape_catalog[ "triangle1" ] ).to( 20 );

To save some typing, if you are referring to the same catalog, you can write:

    wallaroo_within( shape_catalog )
    {
        set_attribute( "base" ).of( "triangle1" ).to( 10 );
        set_attribute( "height" ).of( "triangle1" ).to( 20 );
    }

Wallaroo can throw these exceptions:

Assign attribute values from cfg file

Setting attributes, as well as wiring, can be performed in the configuration file.

XML file syntax

This is a sample of an XML file example:

    <part>
      <name>triangle1</name>
      <class>Triangle</class>
      <attribute>
        <name>base</name>
        <value>10</value>
      </attribute>
      <attribute>
        <name>height</name>
        <value>20</value>
      </attribute>
    </part>

JSON file syntax

This is a sample of a JSON file example:

   "parts":
    [
      {
        "name": "triangle1",
        "class": "Triangle",
        "attribute":
          {
            "name": "base",
            "value": 10
          },
        "attribute":
          {
            "name": "height",
            "value": 20
          }    
      },

Object setup after attributes initialization

With wallaroo attributes you can work around the limit on contructor parameters. However, using attributes instead of constructor parameters requires some care.

The constructor is the place where you perform initialization tasks for your objects, possibly using the constructor parameters.

However, the attribute assignment is performed after the objects are created, i.e. after the constructor calls. This means that inside the constructors your attributes have undefined value, so you cannot use attributes inside the constructors.

To solve this issue, wallaroo provides the methods Catalog::Init() and Part::Init().

If you need the attributes value to perform the initialization of an object, you can override the virtual method Part::Init(). Inside this method you can put the initialization of your object (the code put in the ctor) safely assuming the attributes value are correct.

The method Catalog::Init() calls Part::Init() for each object contained in the Catalog. During the application initialization, you should call Catalog::Init() after the wiring and attribute initialization.

This snippet of code shows how to perform the initialization:

// triangle.h

class Triangle : public wallaroo::Part
{
public:
    virtual void Init()
    {
        // use attributes: here they've been already valorized
    }
    ...
private:
    const Attribute< unsigned int > base;
    const Attribute< unsigned int > height;
};

...

// main.cpp

int main()
{
    ...

    wallaroo_within( shape_catalog )
    {
        set_attribute( "base" ).of( "triangle1" ).to( 10 );
        set_attribute( "height" ).of( "triangle1" ).to( 20 );
    }

    // this calls Init() for every object in the catalog
    shape_catalog.Init();

    ...