Attributes in X++ are special classes that store metadata about classes, methods, tables, fields, and interfaces. They help with tasks like marking methods for special behavior, documentation, and more.
What is an Attribute?
An attribute is a non-abstract class that inherits from the
SysAttribute
class.You can attach attributes to:
Classes
Methods
Class fields
Interfaces
Tables
They are commonly used to map handlers to delegates or define special behavior for framework usage.
Creating an Attribute Class
To create a custom attribute:
Inherit from
SysAttribute
(or a subclass of it).Add a constructor to accept metadata values (like enums or strings).
You can’t directly use
SysAttribute
itself because it’s abstract.
Example:
public class PracticeAttribute extends SysAttribute
{
StartEnd startEndEnum;
str reason;
public void new(StartEnd _startEndEnum, str _reason)
{
startEndEnum = _startEndEnum;
reason = _reason;
}
}
Applying an Attribute
Decorate classes or methods by placing the attribute above them:
[PracticeAttribute(StartEnd::End, "Use this class at the end.")]
public class RegularClass
{
[PracticeAttribute(StartEnd::Start, "Run this method at the beginning.")]
public int rehearse()
{
// Method logic
}
}
You can omit the Attribute
suffix when applying, so [Practice]
is the same as [PracticeAttribute]
.
How Attribute Constructors Work
Attribute constructors can take literal values only (e.g.,
str
,int
,enum
).When a class or method is decorated with an attribute, no instance is created immediately.
The attribute is constructed only when needed, like during reflection or runtime access.
Any constructor errors will show only when the attribute is accessed, not when compiled.
Naming Convention
Attribute class names should end with
Attribute
(e.g.,MyCustomAttribute
).Not required, but recommended for clarity.
SysObsoleteAttribute
One built-in attribute is SysObsoleteAttribute
. It marks classes or methods as obsolete, and can:
Cause compiler warnings or errors
Include a custom message
Example:
[SysObsoleteAttribute("Use Automobile instead; better performance.", false)]
class Bicycle
{
// Bicycle logic
}
Metadata Reflection in X++
To read attribute values at runtime, use the reflection classes:
DictClass
: for classes and interfacesDictMethod
: for class or table methods
Use the following methods:
getAllAttributes()
getAttribute(attributeName)
getAttributedClasses()
getAttributes()
Reflection Example: Check SysEntryPointAttribute on a Method
static public int MetadataOfSysEntryPointAttributeOnMethod(str className, str methodName)
{
int result = -1;
int classId = className2Id(className);
DictMethod method = new DictMethod(UtilElementType::ClassInstanceMethod, classId, methodName);
Object attr = method.getAttribute("SysEntryPointAttribute");
if (attr is SysEntryPointAttribute)
{
SysEntryPointAttribute sepAttr = attr as SysEntryPointAttribute;
result = sepAttr.parmChecked() ? 1 : 0;
}
else
{
result = 2; // Attribute not found
}
return result;
}
Output Meaning:
1
: Attribute exists, value istrue
0
: Attribute exists, value isfalse
2
: Attribute not found
Sample Job to Run the Method:
static void AttributeReflectionJob(Args _args)
{
AttributeReflection::MetadataOfSysEntryPointAttributeOnMethod("CustCustomerService", "create");
}