programming4us
programming4us
ENTERPRISE

Microsoft Dynamic AX 2009 : Reflection APIs (part 2) - Dictionary API

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

2. Dictionary API

The dictionary API is a type-safe reflection API that can reflect on many elements. The following code sample is a revision of the preceding example that finds inventory classes by using the dictionary API. You can’t use this API to get information about when an element was modified. Instead, this example reflects a bit more on the class information and lists only abstract classes.

static void findAbstractInventoryClasses(Args _args)
{
Dictionary dictionary = new Dictionary();
int i;
DictClass dictClass;

for(i=1; i<=dictionary.classCnt(); i++)
{
dictClass = new DictClass(dictionary.classCnt2Id(i));

if (dictClass.isAbstract() &&
strStartsWith(dictClass.name(), 'Invent'))
{
info(strfmt("%1", dictClass.name()));
}
}
}


The Dictionary class provides information about which elements exist. With this information, you can instantiate a DictClass object that provides specific information about the class, such as whether the class is abstract, final, or an interface; which class it extends; whether it implements any interfaces; and what methods it includes. Notice that the DictClass class can also reflect on interfaces. Also notice how the class counter is converted into a class ID; this conversion is required because the IDs aren’t listed consecutively.

When you run this job, you’ll notice that it’s much slower than the implementation that uses the table data API—at least the first time you run it! The job performs better after the information is cached.

Figure 1 shows the object model for the dictionary API. As you can see, some elements can’t be reflected upon by using this API.

Figure 1. The object model for the dictionary reflection API


The following example revises the FindStaticMethodsOnCustTable from the preceding code by using the dictionary API. It also reports the method parameters of the methods.

static void findStaticMethodsOnCustTable(Args _args)
{
DictTable dictTable = new DictTable(tableNum(CustTable));
DictMethod dictMethod;
int i;
int j;
str parameters;

for (i=1; i<=dictTable.staticMethodCnt(); i++)
{
dictMethod = new DictMethod(
UtilElementType::TableStaticMethod,
dictTable.id(),
dictTable.staticMethod(i));

parameters = '';
for (j=1; j<=dictMethod.parameterCnt(); j++)
{
parameters += strfmt("%1 %2",
extendedTypeId2name(dictMethod.parameterId(j)),
dictMethod.parameterName(j));

if (j<dictMethod.parameterCnt())
parameters += ', ';
}
info(strfmt("%1(%2)", dictMethod.name(), parameters));
}
}



As mentioned earlier, reflection can also be used to invoke methods on objects. This example invokes the static Find method on the table CustTable.

static void invokeFindOnCustTable(Args _args)
{
DictTable dictTable = new DictTable(tableNum(CustTable));
CustTable customer;
;
customer = dictTable.callStatic(
tableStaticMethodStr(CustTable, Find), '1201');

print customer.Name; //Prints Sparrow Wholesales
pause;
}


Notice the use of the intrinsic function tableStaticMethodStr to make a reference to the Find method.

You can also use this API to instantiate class and table objects. Suppose you want to select all records in a table with a given table ID. The following example shows you how.

void findRecords(TableId _tableId)
{
DictTable dictTable = new DictTable(_tableId);
Common common = dictTable.makeRecord();
FieldId primaryKeyField = DictTable.primaryKeyField();

while select common
{
info(strfmt("%1", common.(primaryKeyField)));
}
}


First, notice the call to the makeRecord method that instantiates a table cursor object that points to the correct table. You can use the select statement to select records from the table. If you wanted to, you could also insert records by using the table cursor. Notice the syntax used to get a field value out of the cursor object; this syntax allows any field to be accessed by its field ID. This example simply prints the content of the primary key field. You can use the makeObject method on the class DictClass to create an object instance of a class.

All the classes in the dictionary API discussed so far are defined as system APIs. On top of each of these is an application-defined class that provides even more reflection capabilities. These classes are named SysDict<Concept>, and each class extends its counterpart in the system API. For example, SysDictClass extends DictClass.

Consider the following example. Table fields have a property that specifies whether the field is mandatory. The DictField class returns the value of the mandatory property as a bit set in the return value of its flag method. Testing of a bit set is somewhat cumbersome, and if the implementation of the flag changes, the consuming applications breaks. The SysDictField class encapsulates the bit-testing logic in a mandatory method. Here is how the method is used.

static void mandatoryFieldsOnCustTable(Args _args)
{
DictTable dictTable = new DictTable(tableNum(CustTable));
SysDictField sysDictField;
int i;

for (i=1; i<=dictTable.fieldCnt(); i++)
{
sysDictField = new SysDictField(
dictTable.id(), dictTable.fieldCnt2Id(i));

if (sysDictField.mandatory())
info(sysDictField.name());
}
}


You might also want to browse the SysDict classes for static methods. Many of these provide additional reflection information and better interfaces. For example, the SysDictionary class provides a classes method that has a collection of SysDictClass instances. You could use this method to simplify the earlier findAbstractInventoryClasses example.

Notice how all the examples instantiate the dictionary classes by using their new constructor. Some developers use an alternative way to instantiate the dictionary classes, but you should avoid it. Recall the hierarchy of the objects shown in Figure 1. A parent object can return an instance of a child object, as shown here.

DictTable dictTable = new DictTable(tableId);
DictField firstField, nextField;
firstField = dictTable.fieldObject(dictTable.fieldNext(0));
nextField = dictTable.fieldObject(dictTable.fieldNext(dictField.id()));


The primary reason to avoid this construct is that you can’t substitute Dict classes with SysDict classes. If you ever need reflection methods available only on the SysDict classes, you must refactor the code. Writing the code so that it is easy to substitute the class makes refactoring easier and lowers the risk of introducing bugs in the refactoring process. Another reason to avoid this construct is the lack of API consistency. The examples used in this section that instantiate dictionary classes all follow the same structure, which is consistent for all the classes in the dictionary API.

Other  
  •  Microsoft Dynamic AX 2009 : Reflection System Functions
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 4)
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 3)
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 2)
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 1)
  •  Microsoft Enterprise Library : Banishing Validation Complication - How Do I Use The Validation Block?
  •  Microsoft Enterprise Library : Banishing Validation Complication - What Does the Validation Block Do? (part 2)
  •  Microsoft Enterprise Library : Banishing Validation Complication - What Does the Validation Block Do? (part 1)
  •  Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Use the Caching Block (part 4) - Refreshing the Cache, Loading the Cache
  •  Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Use the Caching Block (part 3) - Removing Items from and Flushing the Cache
  •  
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    - Messages forwarded by Outlook rule go nowhere
    - Create and Deploy Windows 7 Image
    - How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
    - Creating and using an unencrypted cookie in ASP.NET
    - Directories
    - Poor Performance on Sharepoint 2010 Server
    - SBS 2008 ~ The e-mail alias already exists...
    - Public to Private IP - DNS Changes
    - Send Email from Winform application
    - How to create a .mdb file from ms sql server database.......
    programming4us programming4us
    programming4us
     
     
    programming4us