Scenario
New field MyNewField as NoYes on CustTrans and VendTrans
Simple solution
Obejcts
Create method parmMyNewField on CustVendTans, CustTrans and VendTrans using Table code extensions.
Usage
custVendTrans.parmMyNewField(NoYes::Yes) will work fine if the record hast been inserted.
Issue
If custVendTrans has not yet been inserted a call to custVendTrans.parmMyFlag(NoYes::Yes) will result in the errors
“Error executing code: CustTrans table does not have method ‘parmMyNewField’.“
or
“Error executing code: VendTrans table does not have method ‘parmMyNewField’.“
Full Solution
Extend the CustVendTransInterface class to properly handle mapped functions irrespective of the record being created or not.
Objects
- Create class MyCustVendTransInterface following plugin design pattern, decorated with [… ExportInterfaceAttribute]
- Create sub-class MyCustTransCustVendTrans
decorated with [… ExportMetadataAttribute(…CustTrans…), … ExportAttribute(…MyCustVendTransInterface…)] - Create sub-class MyVendTransCustVendTrans
decorated with [… ExportMetadataAttribute(…VendTrans…), … ExportAttribute(…MyCustVendTransInterface…)]
- Create sub-class MyCustTransCustVendTrans
[Microsoft.Dynamics.AX.Platform.Extensibility.ExportInterfaceAttribute]
public abstract class MyCustVendTransInterface
{
CustVendTransInterface custVendTransInterface;
private void initializeCustVendTransInterface(CustVendTransInterface _custVendTransInterface)
{
custVendTransInterface = _custVendTransInterface;
}
public CustVendTrans parmCustVendTrans()
{
return custVendTransInterface.parmCustVendTrans();
}
protected void new()
{
}
public static MyCustVendTransInterface createInstance(CustVendTransInterface _custVendTransInterface)
{
SysPluginMetadataCollection metadataCollection = new SysPluginMetadataCollection();
metadataCollection.SetManagedValue(classStr(MyCustVendTransInterface), tableId2Name(_custVendTransInterface.parmCustVendTrans().tableId));
MyCustVendTransInterface instance = SysPluginFactory::Instance(identifierStr(Dynamics.AX.Application), classStr(MyCustVendTransInterface), metadataCollection);
instance.initializeCustVendTransInterface(_custVendTransInterface);
return instance;
}
public NoYes parmMyNewField(NoYes _myNewField= NoYes::No)
{
return _myNewField;
}
}
[System.ComponentModel.Composition.ExportMetadataAttribute(classStr(MyCustVendTransInterface), tableStr(CustTrans))
,System.ComponentModel.Composition.ExportAttribute('Dynamics.AX.Application.MyCustVendTransInterface')]
public class MyCustTransCustVendTrans extends MyCustVendTransInterface
{
private CustTrans parmCustTrans()
{
return this.parmCustVendTrans();
}
public NoYes parmMyNewField(NoYes _myNewField = this.parmCustTrans().MyNewField)
{
CustTrans custTrans = this.parmCustTrans();
custTrans.MyNewField = _myNewField;
return custTrans.MyNewField;
}
}
[System.ComponentModel.Composition.ExportMetadataAttribute(classStr(MyCustVendTransInterface), tableStr(VendTrans))
,System.ComponentModel.Composition.ExportAttribute('Dynamics.AX.Application.MyCustVendTransInterface')]
public class MyVendTransCustVendTrans extends MyCustVendTransInterface
{
private VendTrans parmVendTrans()
{
return this.parmCustVendTrans();
}
public NoYes parmMyNewField(NoYes _myNewField = this.parmVendTrans().MyNewField)
{
VendTrans vendTrans = this.parmVendTrans();
vendTrans.MyNewField = _myNewField;
return vendTrans.MyNewField;
}
}
- Optional: create extenstion class CustVendTransInterface_My_Extension
to provide simple access to the newly created class MyCustVendTransInterface
[ExtensionOf(classStr(CustVendTransInterface))]
final class MyCustVendTransInterfaceCls_Extension
{
private MyCustVendTransInterface MyCustVendTransInterface;
public MyCustVendTransInterface MyCustVendTransInterface()
{
if (!MyCustVendTransInterface)
{
MyCustVendTransInterface = MyCustVendTransInterface::createInstance(this);
}
return MyCustVendTransInterface;
}
}
Usage
//if extension CustVendTransInterface_My_Extension implemented
MyCustVendTransInterface myCustVendTransInterface = CustVendTransInterface::createInstance(custVendTrans).myCustVendTransInterface()
//if extension CustVendTransInterface_My_Extension not implemented
MyCustVendTransInterface myCustVendTransInterface = MyCustVendTransInterface::createInstance(CustVendTransInterface::createInstance(custVendTrans))
//access field
myCustVendTransInterface.parmMyNewField(NoYes::Yes);
Final notes
Microsoft documents the extension of maps here:
Extend table maps that are used as interfaces
However the example SalesPurchTable they are using has a special attribute class to decorate the methods (SalesPurchTableInterfaceFactoryAttribute. The example here is both more generic and simpler.


Leave a Reply