This section describes several design principles to be employed when you design a Microsoft Dynamics AX application.
Keep Business and User Interface Logic Separate
Where to Place the Code
Always Use Field Groups in Tables
Using Global Variables
Use Auto Property Settings
Best Practices for Designing Reports
-----------------------------------------------------------------------------
Keep Business and User Interface Logic Separate
It is very important to have a clear interface between the presentation logic (user interface) and the business logic. Do not mix these two types of logic.
Business logic must be implemented in classes and on tables.
Never design your business logic so that it has direct references to controls on forms or reports. The design of the business logic must enable any relevant form or report to use it.
Remember that the business logic in Microsoft Dynamics AX can be used though COM from other applications. For example, an X++ script can access the business logic that creates a sales quotation. This underscores the importance of not letting the business logic be dependent on a specific Microsoft Dynamics AX form or report.
Where to Place the Code
http://rahulmsdax.blogspot.com/2018/08/where-to-place-code-in-ax.html
Always Use Field Groups in Tables
When designing tables, it is very important to use field groups. You should also add fields to a field group if you are adding fields to existing tables. Add them to an existing field group, if possible.
When you use field groups, IntelliMorph can automatically update the layout of all related forms and reports whenever a modification is made to the field groups.
If you create new forms or reports based on the field groups defined in the standard tables, you will not have to manually update the custom object when the standard tables are modified by an upgrade.
The sequence of the fields in the field groups on tables can be used to determine the sequence of the fields in forms. To do this, use the AutoDataGroup property on the Groups controls in the form design.
This means that the order in which the fields appear in the field group is significant.
Using Global Variables
Global variables are often needed because of flawed implementation designs. However, if used for caching purposes, global variables can provide increases in performance. This topic describes how you can implement a global variable with zero maintenance during an upgrade.
How to Set the Variable
Get the globalCache variable located on the ClassFactory class:
SysGlobalCache globalCache = ClassFactory.globalCache();
Call the set method:
globalCache.set(str owner , anytype key , anytype value );
Parameters
|
Description
|
---|---|
owner
|
A unique name that identifies you as the user. Use classIdGet(this) or classStr(myClass).
|
key
|
Identifies your variable. This is useful if you need more than one global variable from the same location.
|
value
|
The actual value of your variable.
|
Get the Variable
Get the globalCache variable, located on the ClassFactory class:
SysGlobalCache globalCache = ClassFactory.globalCache();
Call the get method:
value = globalCache.get(str owner , anytype key , anytype returnValue = '');
Parameters
|
Description
|
---|---|
owner
|
Must be a unique name that identifies you as the user.
|
key
|
Identifies your variable.
|
returnValue
|
The value you want if the global variable has not been set. This is useful for caching purposes. See the following example.
|
Example
void new(Integer _width = Imagelist::smallIconWidth(), Integer _height = Imagelist::smallIconHeight()) { SysGlobalCache globalCache; Container packedData; ClassName className; ; if (this.keepInMemory()) { globalCache = ClassFactory.globalCache(); className = classId2Name(ClassIdGet(this)); packedData = globalCache.get(className, 0, connull()); imageList = globalCache.get(className+classStr(imagelist), 0, null); } if (!imageList) { imagelist = new Imagelist(_width,_height); this.build(); if (this.keepInMemory()) { globalCache.set(className, 0, this.pack()); globalCache.set(className+classStr(imagelist), 0, imagelist); } } else { this.unpack(packedData); } }
Client/Server Considerations
Because of the duality of ClassFactory, global variables can exist either on the client or the server. This could mean less network traffic because it is possible to have the global variable on both sides—set it twice.
To share your global variable across the network and accept the performance penalty of a client/server call, use the infolog variable (Info class) or appl variable (Application class) instead of ClassFactory. They reside on the client and on the server, respectively.
Use Auto Property Settings
A general design rule is to keep as many property settings set to Auto as possible. The benefit of doing this is that the application objects will automatically adjust to any changes of the kernel’s interpretation the application object’s behavior, such as how a form or report should be displayed.
Best Practices for Designing Reports
This section provides best practices and guidance for creating Microsoft Dynamics AX reports, including how to make a sequence of decisions on the data access, controls, and design for the report.
Elements of Report Design
Data access determines the source of the report’s data set. The data access options for a report include:
- AX Query – A modeled solution for data access.
- X++ Business logic – Use Report Data Provider (RDP) classes to produce a data set.
Controls determine how inputs (parameters) are passed to the report. Controls include:
- Query Ranges – data set filters defined on the AX Query.
- Data Contract – filters for data sets generated from X++ Business logic.
- UI Builder – fully customizable dialogs
Design determines the document layout template of the report. Options for the design include:
- Auto Design – modeled solution for basic layouts
- Precision Design – flexible solution for advanced layout
General Best Practices
The following table provides additional general best practices for developing Microsoft Dynamics AX reports.
Best practice
|
Additional information
|
---|---|
Use query based reports when possible, for best performance.
|
A query to access data has the following advantages:
|
Return a TempDB based temporary table when appropriate.
|
In-Memory tables are not a SQL based concept so the performance is slower than when you return a TmpDB temporary table. This is especially true for large datasets.
|
For calculated fields, use a view wrapped in a query.
|
Views provide the ability to add calculations. For more information, see View Overview.
|
Keep business logic as close to the data as possible.
|
This promotes reuse of business logic. When the business logic filters data, less data is moved through the system and demands fewer resources.
|
Use a precision design for all reports. An auto design is a good start point to create a precision design for a report. An auto design will not create medium or complex reports.
|
For more information, see How to: Create a Precision Design for a Reportand How to: Create an Auto Design for a Report
|
Do not define a sort or a group in a Microsoft Dynamics AX query.
|
The dataset returned to SQL Server Reporting Services will be flattened. Use sort and group in the Reporting Services report definition. For more information, see Working with Data Regions.
|
Use RDP class based reports when calculated fields in a view perform poorly.
|
In reports where there is reuse of one or more expensive calculated fields, performance might improve when you use temporary tables to cache data.
For more information, see How to: Use a Report Data Provider Class in a Report.
|
Avoid using RDP classes when the data for the report is in a table and the report dataset can use the table.
|
RDP classes provide extra flexibility but also introduce complexity and potential performance degradation.
Use an RDP class when the report data needs to be calculated and complex business logic is required to define the data for a report.
When the report data is accessibly in Microsoft Dynamics AX tables, then use a query and display methods or use a view.
|
No comments:
Post a Comment