| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The aspect '<AspectType>' has several layers, but the low-level aspect '<WeaverAspectType>' is ordered between two of these layers. A low-level aspect, which is an aspect implemented by an IAspectWeaver, cannot be ordered between two layers of another aspect because it would split that aspect across two pipeline stages. Add an [assembly: AspectOrder(...)] attribute to order '<WeaverAspectType>' before or after all layers of '<AspectType>'. |
Cause
Most aspects are high-level aspects: they transform code with advice and templates. A low-level aspect is implemented by an aspect weaver, a class implementing IAspectWeaver from the Metalama SDK, which rewrites the syntax tree directly. Some community packages, such as Metalama.Community.Virtuosity, are based on aspect weavers.
Metalama executes the aspects in their order, which is determined by [assembly: AspectOrder] attributes and, when no order is specified, by the aspect names. An aspect weaver always runs in its own stage of the pipeline, and all consecutive high-level aspects run together in another stage. An aspect can have several layers, for instance contract aspects of Metalama.Patterns.Contracts, and all layers of a high-level aspect must run in the same stage.
Metalama reports LAMA0042 when the order of aspects places a low-level aspect between two layers of the same high-level aspect, because this would split that aspect across two stages. In the message, <AspectType> is the aspect with several layers and <WeaverAspectType> is the low-level aspect. This can happen even if you didn't specify any order, when the names of the aspects sort the low-level aspect between the layers of the other aspect. The diagnostic is reported on the aspect class <AspectType>, and Metalama doesn't transform the project.
This diagnostic isn't shown in an example: whether the low-level aspect falls between two layers of the other aspect depends on the default order of all aspect classes visible to the project, including those of referenced aspect libraries, so a small example doesn't reproduce it reliably.
Resolution
Add an assembly-level AspectOrder attribute that orders the low-level aspect <WeaverAspectType> relatively to the aspect <AspectType>, for instance [assembly: AspectOrder( AspectOrderDirection.CompileTime, typeof(MakeVirtualAttribute), typeof(NotNullAttribute) )], where MakeVirtualAttribute is the low-level aspect and NotNullAttribute is the aspect with several layers. Because the attribute orders the aspect types and not individual layers, it moves the low-level aspect before or after all layers of the other aspect.