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
SOSetupInspection
database slot, which depends on theSOSetup
table. In the slot, theSOSetup.InspectionEnabled
value has been cached. - Attached the PXWorkflowDependsOnType attribute to the
Configure method and specified that the workflows of the
form depend on data from the
SOSetup
DAC. - In the Configure method, instead of accessing the
Base
graph, checked theSOSetupInspection.InspecionEnabled
property, which holds the cached value of theSOSetup.InspectionEnabled
property.
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