Thursday, August 9, 2018

D365/AX7 - Code Extensions Using Plugins - SysPluginFactory


Overview

In AX7, the code extensions provide a cleaner way to add your code without modifying the existing one. Most used ways of code extensions include Class Extensions, Delegates and Plugins. Here we are going to look into the code extensions using plugins i.e. SysPluginFactory.Apart from code segregation, plugins play a key role in breaking dependencies between models. Consider the following scenario from existing classes in AX7 for clear understanding.



Here the LedgerDimensionValidationRequest is a member of Ledger model whereas DimensionValidationRequest is a member of Dimensions model. Since LedgerDimensionValidationRequest is a derived class of DimensionValidationRequest, the Ledger model has the reference to the Dimensions model. Therefore, any class in Dimensions model cannot directly use LedgerDimensionValidationRequest to avoid cyclic dependency.
In order to break such dependency, we can use plugins. Plugins use attributes to create subclasses which can be alternatively used by the existing classes and methods in the same plugin base model.
Let’s have a look at how SysPluginFactory is used.

Implementation


Step#1: Create an interface or abstract base class decorated with the attribute ExportInterfaceAttribute.


using Microsoft.Dynamics.AX.Platform.Extensibility;

[ExportInterfaceAttribute()]
public abstract class DimensionValidationRequest implements SysPackable
{

}

Step#2: Create a class to implement the interface or to extend the class created in step1. Apply the attributes below


using System.ComponentModel.Composition;

[ExportMetadataAttribute(enumstr(LedgerDimensionType), LedgerDimensionType::Account)]
[ExportAttribute(identifierstr(Dynamics.AX.Application.DimensionValidationRequest))]
public class LedgerDimensionValidationRequest extends DimensionValidationRequest
{
}

- ExportMetadataAttribute – Parameters are key and value. The key is kept same for all the implementations or subclasses
- ExportAttribute – Parameter is the interface/parent class name

Step#3: To create instance of the class, use the code below


//Instance of the SysPluginMetadataCollection which holds the key-value pair to identify the class
SysPluginMetadataCollection metadataCollection = new SysPluginMetadataCollection();
metadataCollection.SetManagedValue(
enumstr(LedgerDimensionType),
       _ledgerDimensionType);

//Instance of the child class is created using reflection
        DimensionValidationRequest dimensionValidationRequest = SysPluginFactory::Instance(
            identifierstr(Dynamics.AX.Application),
            classstr(DimensionValidationRequest),
            metadataCollection);


Instead of using enumstr or classstr, simple string values can also be used. However, using these methods are more useful than the simple string text. Enums can be used conveniently for identifying the multiple implementations of a base class.
In this way the SysPluginFactory helps to create instance of the classes without the need for the child class reference in the base model and similarly, multiple implementations of the interface or class can be added without making changes to the base class.

No comments:

Post a Comment