Minimizing the footprint of changes

The footprint we make on existing objects is a key consideration when it comes to solution maintainability and the associated costs.

Microsoft has made key investments in the development environment in order to make it easier to write code in such a way that it sits alongside another party's solution. The advantage for Microsoft is that their customers can adopt multiple solutions or add-ons from ISVs with minimum effort.

Prior to AX 2012, this effort would have involved merging code from different partners and additional effort would have been required to ensure that a hotfix from one organization did not regress code in another add-on.

The next sections will highlight the practices and technologies that accomplish this.

Where to make the change

We are often asked to make changes to AX that require standard objects to be modified; often, the difficult decision is about where the change is to be made.

Firstly, we should consider how the code is structured by taking the example of a form that acts upon a table. Tables are structured into fields, field groups, indexes, relations, delete actions (for example, cascading the deletion to child tables), and methods. Forms are structured into form-level methods, data sources (a reference to a table), and controls. A request might be, "Can we make the vehicle field on the transport form mandatory?"

This is possible; the form control does have this property, as do the data source field and the equivalent field on the table—so, which of these to use? The answer is always as high in the stack as possible. The requirement is that the table always has this particular field filled in, so wherever this field is added, it should be mandatory.

The same pattern applies to code changes—always at the highest level and in this order: class, table, form data source field/method, form control.

Note

Making changes to form controls is very rarely required, and should be considered as a deviation from best practices.

Even hiding controls on forms should be handled in a method (which is usually called enableControls), as this makes the change more obvious and much easier to read, extend, and reuse.

The use of field groups

We may already use field groups, and it is best practice to do so. It may seem strange at first that we are creating what are essentially UI components in the data layer, but this pays off in terms of consistent UI and reduced footprint on standard AX. Forms dynamically display the fields that are in that field group; by adding a new field to the appropriate field group, the forms magically display this new field.

The reason this reduces footprint is because we are making one change that affects all forms that refer to the field group, and doesn't affect the form when applying updates.

Eventing

Eventing is a new key feature in AX 2012 that, along with models, is a key enabler for ISVs to write add-ons for AX.

Event subscription

This technology allows you to subscribe to an event in AX. So, instead of modifying the method, we simply subscribe to it as a pre- or post-event. We can then perform our logic elsewhere in an X++ or a .NET assembly, and even modify method parameters and return values.

This subscription is not a modification to the source method. Therefore, a method can have subscriptions in several different models in the same layer.

Delegates

Delegates are empty method stubs to which we subscribe. They are created by the original author and called from within their code. This is done so that you can subscribe to events that happen within a method without modifying a method.

For example, the following lines of code would be a delegate written by an ISV (Axp is the prefix used by this ISV):

delegate void weightCaptured(AxpWeighTicketContract _contract)
{
}

The ISV will then call this delegate at the appropriate time with the data contract. By subscribing to this delegate, you can handle the event and perform the necessary tasks with the supplier contract. This provides a hook into the supplied solution without modifying it. For more information about the guidelines on delegates, visit http://msdn.microsoft.com/en-us/library/gg879953.aspx.

Extending a class

Another method of modifying behavior with a minimal footprint is to extend the class. This should be done only if you cannot perform the task through an event subscription.

The pattern is implemented with the following steps:

  1. Create a new class and use the extends keyword to extend the class you need to change.
  2. Override the method you wish to change.
  3. Modify the construct method on the base class so that it constructs your class based on the criteria you want.

Table-level form events

The table has several events that happen based on form events. In this example for the modified event, the mechanism is conceptualized as follows:

  • A data bound field's modified event will call the data source field's modified method
  • The bound data source field's modified event will call the table's modifiedField event with the field ID of the field being modified

The table's modified event is normally a large switch statement based on the field ID parameter with a case for each handled field. To modify this, we can simply add a case for our new field or change the behavior of an existing case.

In this situation, we should subscribe to the modifiedField method, but another option would be to create a new method with the same profile. This is preferable if we are the end-user organization, but is essential for VARs and ISVs. This is done by copying the method header. Let's take a look at the following example:

public void modifiedField(FieldId _fieldId)

We can then create a new method, as follows:

public void conModifiedField(FieldId _fieldId)

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

We can then create a switch statement to handle the fields we need to in this new method. In order to call this new method, we can then add a call to our new method in the original modifiedField method:

public void modifiedField(FieldId _fieldId)
{
    super(_fieldId);
    switch (_fieldId)
    {
        case fieldNum(<TableName>, <FieldName>):
            // code
            break;
    }
    // Con Var modification by SB 2014/06/09 handle custom fields
    this.conModifiedField(_fieldId);
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.140.204