Skip to content

Latest commit

 

History

History
123 lines (96 loc) · 4.85 KB

File metadata and controls

123 lines (96 loc) · 4.85 KB

PX1114

This document describes the PX1114 diagnostic.

Summary

Code Short Description Type Code Fix
PX1114 A graph extension should not inherit from a terminal graph extension. Warning Unavailable

Diagnostic Description

The PX1114 diagnostic identifies graph extensions that inherit from terminal graph extensions. A terminal graph extension is a graph extension that will be instantiated by Acumatica Framework at runtime during the initialization of the corresponding graph.

Currently, there are two types of terminal extensions:

  1. Non-abstract and non-generic graph extension: A concrete graph extension without generic type parameters.
  2. Abstract graph extension with PXProtectedAccess attribute: An abstract graph extension decorated with the [PXProtectedAccess] attribute.

Having a terminal graph extension among graph extension's base classes may cause confusion and be undesired for a developer because graph event handlers declared in the base terminal extension will be subscribed to Acumatica events twice - once for the base terminal extension and once for the derived extension. This may lead to unexpected behavior, such as event handlers being executed twice. For this reason, inheriting from terminal graph extensions is discouraged and the PX1114 diagnostic issues a warning for graph extensions derived from terminal extensions. For rare scenarios where such inheritance is intentional, you may suppress the warning with Acuminator suppression comment.

Example of Incorrect Code

Case 1: Inheriting from Non-Abstract Graph Extension

public class SomeGraph : PXGraph<SomeGraph>
{
	// Business logic here
}

// Non-abstract graph extension - this is a terminal extension
public class NonAbstractGraphExtension : PXGraphExtension<SomeGraph>
{
	// Extension logic here
}

// This graph extension inherits from a non-abstract extension - PX1114 violation
public class DerivedGraphExtension : NonAbstractGraphExtension
{
	// Additional logic here
}

Case 2: Inheriting from Graph Extension with PXProtectedAccessAttribute

public class SomeGraph : PXGraph<SomeGraph>
{
	// Business logic here
}

// Abstract graph extension with PXProtectedAccess - still considered terminal
[PXProtectedAccess]
public abstract class PXProtectedAccessExtension : PXGraphExtension<SomeGraph>
{
	// Extension logic here
}

// This graph extension inherits from PXProtectedAccess extension - PX1114 violation
public class DerivedFromProtectedExtension : PXProtectedAccessExtension
{
	// Additional logic here
}

Example of Correct Code

Case 1: Inheriting from Abstract Graph Extension

public class SomeGraph : PXGraph<SomeGraph>
{
	// Business logic here
}

public abstract class AbstractGraphExtension : PXGraphExtension<SomeGraph>
{
	// Extension logic here
}

// This graph extension inherits from an abstract graph extension - no error
public class DerivedGraphExtension : AbstractGraphExtension
{
	// Additional logic here
}

Case 2: Inheriting from Abstract Graph Extension that use PXProtectedAccessAttribute to Access Protected Members

public class SomeGraph : PXGraph<SomeGraph>
{
	protected void Foo(){ }
}

// Abstract graph extension without PXProtectedAccess on the extension class itself can still declare members with [PXProtectedAccess]
// to access protected members of the base graph and its base graph extensions
// Such graph extensions are not considered terminal, they won't be instantiated at runtime.
public abstract class PXProtectedAccessExtension : PXGraphExtension<SomeGraph>
{
	[PXProtectedAccess]
	protected abstract void Foo();
}

// This graph extension inherits from PXProtectedAccess extension which is not considered terminal - no error
// Notice that DerivedFromProtectedExtension has to be abstract and declare [PXProtectedAccess] attribute as well since its base class accesses protected members of the base graph
[PXProtectedAccess]
public class DerivedFromProtectedExtension : PXProtectedAccessExtension
{
	// Additional logic here
}

Related Articles