This document describes the PX1099 diagnostic.
Code | Short Description | Type | Code Fix |
---|---|---|---|
PX1099 | The API reported by the diagnostic should not be used with the Acumatica Framework. | Warning | Unavailable |
The PX1099 diagnostic detects APIs that should not be used with the Acumatica Framework. Each banned API may have its own reason for being banned. The next section provides an example of a banned API with the Math.Round
overloads that do not specify a method for rounding a midpoint.
By default, the System.Math.Round
method uses Banker's rounding, an algorithm that rounds the midpoint to the nearest even number.
This means that 12.5
will be rounded to 12
and 13.5
to 14
. This behavior is not compatible with Microsoft Excel rounding, which by default uses midpoint rounding away from zero.
This behavior also surprises many developers, who expect midpoint rounding away from zero which is better known.
On the other hand, Banker's rounding to even has its own advantages. The midpoint rounding away from zero on average has a bigger rounding error than Banker's rounding because more numbers are rounded up than down. With the away-from-zero rounding, the rounding error from multiple operations will be bigger on average.
You can use either type of rounding, but it is important to understand which one is used in the code and to be consistent and explicit with it. Thus, the PX1099 diagnostic forbids the Math.Round
method overloads that do not specify a method for rounding a midpoint.
In the following example, a forbidden overload of the System.Math.Round
is used.
public class MyGraph : PXGraph<MyGraph>
{
public virtual decimal CalculateCuryAmount(decimal amount, decimal curyRate, int precision)
{
// The rounding used by default will be Banker's Rounding, which rounds the midpoint to the nearest even number. This behavior can be unexpected for developers who are used to rounding away from zero.
return Math.Round(amount * curyRate, precision);
}
}
This example shows how to specify the Math.Round
method with the MidpointRounding.AwayFromZero
parameter to round the midpoint away from zero.
public class MyGraph : PXGraph<MyGraph>
{
public virtual decimal CalculateCuryAmount(decimal amount, decimal curyRate, int precision)
{
return Math.Round(amount * curyRate, precision, MidpointRounding.AwayFromZero);
}
}
The main idea of the PX1099 analysis is that all API usages in the checked code are checked against a list of forbidden APIs. The API is reported if any of the following criteria is met:
- The API itself is in the list of banned APIs.
- A namespace containing an API is in the list of banned APIs.
- One of the types contains an API is in the list of banned APIs. In case of nested types, the API is banned if any of containing types is in the list of banned APIs.
- The API is a type and one of its base types is in the list of banned APIs.
- The API is a method, property or event; also it is an override of a base type member, and one of the overridden members is in the list of banned APIs.
The diagnostic also supports a list of allowed APIs that are not reported even if they are recognized as forbidden. For example, the analysis reports the System.Environment
type and all its members as forbidden.
However, the System.Environment.NewLine
property is allowed and is not reported by the PX1099 diagnostic. The list of allowed APIs makes it possible to avoid frequently reported false positives and to configure analysis more granularly.
The PX1099 diagnostic provides advanced configuration options that you can use to customize the diagnostic behavior. You can disable the PX1099 diagnostic or configure custom files with banned and allowed APIs.
You can find the PX1099 settings in the following Acuminator section of Visual Studio settings: Tools -> Options -> Acuminator -> Banned API
.
The following settings are available:
Enable PX1099 diagnostic for banned APIs
: Enables or disables the PX1099 diagnostic. By default, the diagnostic is enabled.Banned APIs File
: Specifies the path to the file with banned APIs.Allowed APIs File
: Specifies the path to the file with allowed APIs.
Acuminator comes with default lists of banned and allowed APIs. These files are deployed by Acuminator on your machine in the <My Documents Folder>\Acuminator\Acumatica Banned API
folder.
The Banned APIs File
and Allowed APIs File
settings are initially set to these files. You can modify these files to customize the list of banned and allowed APIs.
Note, that clearing the Banned APIs File
and Allowed APIs File
settings in Visual Studio will not prevent the PX1099 diagnostic from running. The diagnostic will use the default lists of banned and allowed APIs that are
embedded in the Acuminator assemblies. To disable the PX1099 diagnostic, you need to set the Enable PX1099 diagnostic for banned APIs
setting to false
.
The following table shows the default banned APIs that are included in the Acuminator.
API Name | API Type | API Ban Type | Ban Reason |
---|---|---|---|
System.Math.Round(double) |
Method | General | Math.Round uses Banker's Rounding by default, which rounds to the closest even number. Usually, this is not the desired rounding behavior. Use the Math.Round overload with the MidpointRounding parameter to explicitly specify the desired rounding behavior. |
System.Math.Round(decimal) |
Method | General | Math.Round uses Banker's Rounding by default, which rounds to the closest even number. Usually, this is not the desired rounding behavior. Use the Math.Round overload with the MidpointRounding parameter to explicitly specify the desired rounding behavior. |
System.Math.Round(double, int) |
Method | General | Math.Round uses Banker's Rounding by default, which rounds to the closest even number. Usually, this is not the desired rounding behavior. Use the Math.Round overload with the MidpointRounding parameter to explicitly specify the desired rounding behavior. |
System.Math.Round(decimal, int) |
Method | General | Math.Round uses Banker's Rounding by default, which rounds to the closest even number. Usually, this is not the desired rounding behavior. Use the Math.Round overload with the MidpointRounding parameter to explicitly specify the desired rounding behavior. |
System.Data.Entity |
Namespace | ISV | Use of the System.Data.Entity namespace is forbidden in Acumatica customization projects. |
System.Data.SqlClient |
Namespace | ISV | Use of the System.Data.SqlClient namespace is forbidden in Acumatica customization projects. |
System.AppDomain |
Type | ISV | Use of the AppDomain type is forbidden in Acumatica customization projects. |
System.Diagnostics.ProcessStartInfo |
Type | ISV | Use of the ProcessStartInfo type is forbidden in Acumatica customization projects. |
System.Environment |
Type | ISV | Use of the Environment type is forbidden in Acumatica customization projects. |
System.IO.File |
Type | ISV | Use of the File type is forbidden in Acumatica customization projects. |
System.GC |
Type | ISV | Access to garbage collector is forbidden in Acumatica customization projects. |
System.OperatingSystem |
Type | ISV | Use of the OperatingSystem type is forbidden in Acumatica customization projects. |
System.Reflection.MethodInfo |
Type | ISV | Use of reflection is forbidden in Acumatica customization projects. |
PX.Common.WebConfig |
Type | ISV | Access to the WebConfig type is forbidden in Acumatica customization projects. |
System.Threading.Tasks.Parallel |
Type | General | Use of the Parallel type is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
System.Linq.ParallelEnumerable.AsParallel all overloads |
Method | General | Use of Parallel LINQ is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
System.Threading.Tasks.Task.Run all overloads |
Method | General | Use of the Task.Run method is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
System.Threading.Tasks.Task.Run<TResult> all overloads |
Method | General | Use of the Task.Run method is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
System.Threading.Tasks.Task.Start all overloads |
Method | General | Use of the Task.Start method is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
System.Threading.Tasks.Task.ConfigureAwait(bool) |
Method | General | Use of the Task.ConfigureAwait method is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
System.Threading.Tasks.Task<TResult>.ConfigureAwait(bool) |
Method | General | Use of the Task.ConfigureAwait method is forbidden in Acumatica because it may lead to deadlocks and a loss of Acumatica synchronization context. It also prevents Acumatica request profiler and resource governor from correctly managing system resources. |
You can also find the latest version of this list in the Acuminator GitHub repository: https://github.com/Acumatica/Acuminator/blob/dev/src/Acuminator/Acuminator.Utilities/BannedApi/Data/BannedApis.txt
The following table shows the default allowed APIs that are included in the Acuminator.
API Name | API Type |
---|---|
System.Environment.NewLine |
Property |
You can also find the latest version of the white list in the Acuminator GitHub repository: https://github.com/Acumatica/Acuminator/blob/dev/src/Acuminator/Acuminator.Utilities/BannedApi/Data/AllowedApis.txt
The records in the file with banned APIs have the same API format. Each API record is represented by a single line in the file and consists of the following three parts separated by a whitespace:
- A mandatory API identifier.
- A mandatory API ban type that indicates for whom API is banned. There are two available values:
General
indicates that the API is banned for all developers.ISV
indicates that the API is banned for ISV developers only.
- An optional API ban reason. This is a string that explains why the API is banned.
The API identifier is based on the DocID
format, which was chosen due to its convenience. For more information, see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/#id-strings.
This format is widely used by .Net technology, and Roslyn already has built-in functionality to generate DocID
for APIs.
However, the DocID
format has been enhanced in Acuminator to store more information about the API as follows:
- In the full API name, the namespace part is separated from the containing type names with a special hyphen (
-
) separator. Acuminator uses the separator to deduce which part of the API name is the namespace. This capability is impossible in the standardDocID
format. An example of an API name with a namespace is shown in the following string.T:System-Environment
- If the full API name includes nested types, then their names are separated by a plus sign (
+
) to simplify the parsing of the API name into parts, as shown in the following example.T:Microsoft.AspNet.Mvc.ModelBinding-ModelStateDictionary+PrefixEnumerable
The file with allowed APIs has the same format as the file with banned APIs. However, the "API Ban Type" part, while being mandatory is ignored by Acuminator. We recommend that you always set this type to General
.
The API ban reason in the file with allowed APIs is not used by Acuminator and should be omitted.