Changes in the Application Code (C#)
In this section, you can find information about the customization of the application functionality, which is provided by the application business logic (implemented in C# code) of data access classes and business logic controllers.
BLC and DAC Extensions
To give you the ability to customize the functionality or behavior of a form, the MYOB Acumatica Customization Platform uses technology based on extension models. When you are resolving a typical customization task, you generally create extensions for original data access classes and business logic controllers.
An extension for a business logic controller (BLC, also referred to as graph) or a data access class (DAC) is a class derived from a generic class defined in the PX.Data assembly of MYOB Acumatica. To declare an extension for a DAC, you derive a class from the PXCacheExtension<T> generic class. To declare an extension of a BLC, you derive a class from the PXGraphExtension<T> generic class.
At run time, during the first initialization of a base class, the MYOB Acumatica Customization Platform automatically finds the extension for the class and applies the customization by replacing the base class with the merged result of the base class and the extension it found.
When you unpublish all customization projects, the platform deletes all the code files from the App_RuntimeCode folder. As a result, the platform has no custom code to merge at run time.
Multilevel Extensions
The MYOB Acumatica Customization Platform supports multilevel extensions, which are required when you develop off-the-shelf software that is distributed in multiple editions. Precompiled extensions provide a measure of protection for your source code and intellectual property.
The figure below illustrates the DAC extension model.
The figure below illustrates the BLC extension model.
You can use multilevel extensions to develop applications that extend the functionality of MYOB Acumatica or other software based on MYOB Acumatica Framework in multiple markets (that is, specified categories of potential client organizations). You may have a base extension that contains the solution common to all markets as well as multiple market-specific extensions. Every market-specific solution is deployed along with the base extension. Moreover, you can later customize deployed extensions for the end user by using DAC and graph extensions.
The Order in Which Extensions Are Loaded
- The system collects extensions for the DAC or graph type.
- The system sorts the list of extensions in alphabetical order.
- If there is a subscriber to the
PX.Data.PXBuildManager.SortExtentions event, the system passes the
list of extensions in alphabetical order to this subscriber, which can sort extensions
in a custom way. A sample implementation of the subscriber is shown in the following
code.Note:Make sure you use a stable sorting method as the following example does.
using System; using System.Collections.Generic; using System.Linq; using System.Web.Compilation; using Autofac; using PX.Data.DependencyInjection; namespace MyLib { public class ServiceRegistration : Module { protected override void Load(ContainerBuilder builder) { builder.ActivateOnApplicationStart<ExtensionSorting>(); } private class ExtensionSorting { private static readonly Dictionary<Type, int> _order = new Dictionary<Type, int> { { typeof(MultiCurrency), 4 }, { typeof(SalesPrice), 3 }, { typeof(Discount), 2 }, { typeof(SalesTax), 1 }, { typeof(MyGraphExt1), -1 }, { typeof(MyGraphExt2), -2 }, }; public ExtensionSorting() { PXBuildManager.SortExtensions += StableSort; } private static void StableSort(List<Type> list) { if (list?.Count > 1) { var stableSortedList = list.OrderByDescending(item => _order.ContainsKey(item) ? _order[item] : 0).ToList(); list.Clear(); list.AddRange(stableSortedList); } } } } }
- The system changes the order of dependent extensions (such as
Dac1Ext: PXCacheExtension<Dac1>
andDac1ExtExt: PXCacheExtension<Dac1Ext, Dac1>
) so that the higher-level extensions have higher priorities during the merge operation.
MyLib
and
ExternalLib
namespaces, and the customization project includes an
external sorter, which sorts the extensions in a custom way. The following diagram shows how
these extensions are sorted. As a result of the sorting in this example, the first extension
that is applied is MyLib.ContactExt
. The
ExternalLib.ExtExtForContact
class has the highest priority during the
merge operation.