Screen Configuration: Restrictions of the Configure Method
You should be aware of the limitations of the Configure method when you are working with it. These limitations are described in the following sections.
Creation of Graph Instances and Base Graph Access
Inside the Configure method, you should not create a graph
instance or access the Base graph because either of these actions
can lead to deadlocks. If you need to read data from the database, you can use
database slots by doing the following:
- In the graph extension where you need to define the Configure method, you also define a database slot that is based on the DAC from which you need to read data. In the slot, you cache the data that you need to access.
- You attach the PXWorkflowDependsOnType attribute to the Configure method and specify the DAC from which you want to read data.
- In the Configure method, you access the data from the slot.
For example, suppose that you need to enable the extension in the
Configure method only if the
InspectionEnabled property of SOSetup DAC is
true. The following code shows how you can access the
InspectionEnabled property by using a database slot.
private class SOSetupInspection : IPrefetchable
{
public static bool InspectionEnabled =>
PXDatabase.GetSlot<SOSetupInspection>("SOSetupInspection", typeof(SOSetup))._inspectionEnabled;
private bool _inspectionEnabled;
void IPrefetchable.Prefetch()
{
using (PXDataRecord soSetup =
PXDatabase.SelectSingle<SOSetup>(new PXDataField<SOSetup.inspectionEnabled>()))
if (soSetup != null) _inspectionEnabled = (bool)soSetup.GetBoolean(0);
}
}
[PXWorkflowDependsOnType(typeof(SOSetup))]
public sealed override void Configure(PXScreenConfiguration config){
//if (!Base.sosetup.Current.InspectionEnabled) return;
if (!SOSetupInspection.InspectionEnabled) return;
...
}
The code above has done the following:
- In the extension, defined the
SOSetupInspectiondatabase slot, which depends on theSOSetuptable. In the slot, theSOSetup.InspectionEnabledvalue has been cached. - Attached the PXWorkflowDependsOnType attribute to the
Configure method and specified that the workflows of the
form depend on data from the
SOSetupDAC. - In the Configure method, instead of accessing the
Basegraph, checked theSOSetupInspection.InspecionEnabledproperty, which holds the cached value of theSOSetup.InspectionEnabledproperty.
For more information on database slots, see Use of Slots to Cache Data Objects.
Customization with the PXOverride Mechanism
sealed modifier in C# when you are
overriding the Configure method. The following code shows the
recommended way of overriding the Configure
method.//Use sealed modifier explicitly to specify that this method cannot be overridden
public sealed override void Configure(PXScreenConfiguration config) =>
Configure(config.GetScreenConfigurationContext<TGraph, TPrimaryEntity>());
//Replace the TGraph and TPrimaryEntity above with your actual graph and DAC classes, respectively
Access to an Instance State
public sealed override void Configure(PXScreenConfiguration config) =>
Configure(config.GetScreenConfigurationContext<TGraph, TPrimaryEntity>());
//Apply workflow changes in a static method
//Replace the TGraph and TPrimaryEntity below with your actual graph and DAC classes, respectively
protected static void Configure(WorkflowContext<TGraph, TPrimaryEntity> context)
{
...
context.AddScreenConfigurationFor(screen => screen
...
);
}
Graph Class Hierarchy
The Configure method is present both in graphs and graph
extensions. The methods have the same signature. However, there are notable
differences in how they behave at runtime. The Configure method
in a graph is treated more like a static method than an instance virtual method by
the MYOB Acumatica Framework. You can notice this phenomenon when working with a graph class hierarchy.
Suppose that you have a Base graph and a Derived
graph that is derived from the Base graph. The
Base graph declares a workflow as shown in the following code.
public class Base : PXGraph<Base>
{
public override void Configure(PXScreenConfiguration screenConfig)
{
//Some workflow logic here
}
}
The code above has defined the screen configuration for the base graph. However, this
Configure method will not be called for the
Derived graph, and its screen configuration will remain empty
because the system ignores all derived graphs while processing screens. Notice that
the Configure method is not sealed in the Base
graph. To make sure that the Configure method in the
Base graph gets called for the Derived graph,
you might attempt to declare a trivial override of the Configure
method in the Derived graph. An example is shown in the following
code.
public class Derived : Base
{
public override void Configure(PXScreenConfiguration screenConfig)
=> base.Configure(screenConfig);
}
It is important to note that overriding a graph's Configure method
in a derived graph, as shown in the preceding code example, is not allowed. We
recommend that you explicitly seal the Base graph's
Configure method to prevent such override attempts. When the
Configure method is used in graph extensions, the MYOB Acumatica Framework treats it like a normal virtual method. The caveats discussed above with regard
to the Configure method in a graph do not apply in this instance,
but you still should avoid relying on the Configure method's
virtuality in a graph extension. You should instead explicitly seal the
Configure method in graph extensions as well.
Order of Execution
The Configure method override in a graph is always executed first. The order of execution for multiple Configure methods declared in several graph extensions is defined by the way the graph extensions are chained and their explicit sort order. For more details, see To Sort Multiple Generic Graph Extensions
