Open sandboxFocusImprove this doc

LAMA0229: A run-time-or-compile-time type can't be nested in a run-time class

Severity Error
Reported by Metalama.Framework
Message The type '<Type>' cannot be both run-time and compile-time, like an aspect class or a [RunTimeOrCompileTime] class, because it is nested in a run-time-only type. Move it out of the containing type.

Cause

Metalama builds a separate compile-time assembly that contains your aspects, fabrics, and other compile-time code. Run-time-only types aren't copied to this assembly. When a run-time type contains nested types, Metalama only extracts the nested types that are compile-time only, such as type fabrics. It can't extract a type that must exist both at run time and at compile time.

Metalama reports LAMA0229 when a type whose scope is both run-time and compile-time is nested in a run-time-only type. This applies to every kind of type (class, struct, record, interface, enum, or delegate) marked with [RunTimeOrCompileTimeAttribute], and implicitly to aspect classes, because IAspect is run-time-or-compile-time.

In the following example, the Log aspect class is nested in the OrderService class.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0229.Error;
5
6internal class OrderService
7{
8    [Log]
9    public void PlaceOrder( string product, int quantity ) { }
10
11    // Error: an aspect class can't be nested in a run-time class.
    Error LAMA0229: The type 'OrderService.LogAttribute' cannot be both run-time and compile-time, like an aspect class or a [RunTimeOrCompileTime] class, because it is nested in a run-time-only type. Move it out of the containing type.

12    public class LogAttribute : OverrideMethodAspect
13    {
14        public override dynamic? OverrideMethod()
15        {
16            Console.WriteLine( $"Executing {meta.Target.Method}." );
17
18            return meta.Proceed();
19        }
20    }
21}
22

Resolution

Move the type out of the run-time type, for instance to the namespace level, as in the following example.

If the type only needs to exist at compile time, you can instead mark it with [CompileTimeAttribute], but only private type fabrics can be nested in a run-time type (see LAMA0230 and LAMA0231), so you'll usually still need to move it.

Source Code
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0229.Fixed;
5
6internal class OrderService
7{
8    [Log]
9    public void PlaceOrder( string product, int quantity ) { }
10}
11



12// Fixed: the aspect class is declared at the namespace level.
13public class LogAttribute : OverrideMethodAspect
14{




15    public override dynamic? OverrideMethod()
16    {
17        Console.WriteLine( $"Executing {meta.Target.Method}." );
18
19        return meta.Proceed();


20    }
21}
22
Transformed Code
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0229.Fixed;
5
6internal class OrderService
7{
8    [Log]
9    public void PlaceOrder(string product, int quantity)
10    {
11        Console.WriteLine("Executing OrderService.PlaceOrder(string, int).");
12    }
13}
14
15// Fixed: the aspect class is declared at the namespace level.
16
17#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
18
19
20public class LogAttribute : OverrideMethodAspect
21{
22    public override dynamic? OverrideMethod() => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
23}
24
25#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
26
27
28

See also