Decorating classes/methods – SysAttrib

A cool new thing introduced in AX 2012 is the SysAttribute framework allowing the developer to decorate classes and methods with attributes.
This is heavily utilized in the upgrade framework but can definately be used in lots of scenarios. One of the real sweet things is allowing the developer to instantiate objects from a class selected based on its attributes. This is a way more flexible approach than the classic construct methods.
I have created a small example to show how it works. The example has 3 parts:
1. The attribute definition.
2. The classes with the above attributes.
3. An executing class that instantiates objects of the above classes.
The attribute definition looks like this:
class TestClassAttribute extends SysAttribute
{
    TableGroupAll   tableGroupAll;
}
public void new(tableGroupAll _tableGroupAll)
{
    super();
    tableGroupAll = _tableGroupAll;
}
public TableGroupAll parmTableGroupAll(TableGroupAll _tableGroupAll = tableGroupAll)
{
    tableGroupAll = _tableGroupAll;
    return tableGroupAll;
}
There is not much more to it than this. Offcourse you can define more attributes but for this demo this will do.
Now we need to create the classes to use the attribute. To begin with we create an abstract class the other classes can extend:
abstract class TestClassExtensionBase
{
    TableGroupAll type;
}
public void run()
{
    info(enum2str(type));
}
It does not do that much. Define a variable of type TableGroupAll and put the value of the variable into the infolog.
The classes extending our abstract classes look like this:
[TestClassAttribute(TableGroupAll::Table)]
class TestClassExtensionTable extends TestClassExtensionBase
{
}
public void new()
{
    type = TableGroupAll::Table;
}

[TestClassAttribute(TableGroupAll::GroupId)]
class TestClassExtensionGroup extends TestClassExtensionBase
{
}
public void new()
{
    type = TableGroupAll::GroupId;
}
[TestClassAttribute(TableGroupAll::All)]
class TestClassExtensionAll extends TestClassExtensionBase
{
}
public void new()
{
    type = TableGroupAll::All;
}
Very similar to eachother. Notice how the classdeclaration has been decorated with the TestClassAttribute attribute. The parameter profile matches the new-method on the TestClassAttribute-class.
The type variable is set in the new-method so it is set as expected when the run method in the super class is executed.
Finally, the class doing the work. First of all a declaration of a variable to hold the object we want to create.
class TestGetObjectFromAttrib
{
    TestClassExtensionBase  test;
}
Then a method that based on the parsed TableGroupAll parameter instantiate and uses the class. The SysExtensionAppClassFactory::getClassFromSysAttribute locates, instantiates and returns an object based of the abstract class based on the attribute profile :
private void getAndRunFromAttribute(TableGroupAll _type)
{
    TestClassAttribute    attribute;
    attribute = new TestClassAttribute(_type);
    test = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(TestClassExtensionBase), attribute);
    info(classId2Name(classIdGet(test)));
    test.run();
    info('---------------');
}

The run method then calls this method with the three different values of the TableGroupAll enum:

private void run()
{
    // Type = table
    // ------------
    this.getAndRunFromAttribute(TableGroupAll::Table);

    // Type = group
    // ------------
    this.getAndRunFromAttribute(TableGroupAll::GroupId);

    // Type = all
    // ------------
    this.getAndRunFromAttribute(TableGroupAll::All);
}
Finally, a main method that executes it all.
public static void main(Args args)
{
    new TestGetObjectFromAttrib().run();
}

The result should look something like this:

Image
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s