| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The compile-time type '<NestedType>' cannot be nested in a run-time type. The only compile-time types that can be nested in a run-time type are classes derived from '<TypeFabric>'. Move '<NestedType>' out of the containing type. |
Cause
Metalama builds a separate compile-time assembly that contains your compile-time code, but not your run-time types. The only compile-time types that Metalama extracts from a run-time type are type fabrics, that is, classes derived from TypeFabric, because a type fabric amends the type that contains it.
Metalama reports LAMA0231 when any other compile-time type is nested in a run-time type: a class that doesn't derive from TypeFabric, for instance a ProjectFabric or a class marked with [CompileTimeAttribute], or a compile-time struct, record, interface, enum, or delegate. The second placeholder of the message is TypeFabric.
In the following example, a project fabric is nested in the OrderService class.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0231.Error;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 Console.WriteLine( $"Executing {meta.Target.Method}." );
11
12 return meta.Proceed();
13 }
14}
15
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Fabrics;
3
4namespace Doc.LAMA0231.Error;
5
6internal class OrderService
7{
8 public void PlaceOrder( string product, int quantity ) { }
9
10 public void CancelOrder( int orderId ) { }
11
12 // Error: only a type fabric can be nested in a run-time class.
Error LAMA0231: The compile-time type 'OrderService.Fabric' cannot be nested in a run-time type. The only compile-time types that can be nested in a run-time type are classes derived from 'TypeFabric'. Move 'OrderService.Fabric' out of the containing type.
13 private class Fabric : ProjectFabric
14 {
15 public override void AmendProject( IProjectAmender amender )
16 {
17 amender.SelectTypes()
18 .Where( t => t.Name == "OrderService" )
19 .SelectMany( t => t.Methods )
20 .AddAspect<LogAttribute>();
21 }
22 }
23}
24
Resolution
Depending on your intent, do one of the following:
- If the nested type is meant to amend its containing type, derive it from TypeFabric, as in the following example. Keep it
private(see LAMA0230). - Otherwise, move the type out of the run-time type, for instance to the namespace level. Project fabrics and compile-time helper types are usually top-level types.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0231.Fixed;
5
6public class LogAttribute : OverrideMethodAspect
7{
8 public override dynamic? OverrideMethod()
9 {
10 Console.WriteLine( $"Executing {meta.Target.Method}." );
11
12 return meta.Proceed();
13 }
14}
15
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Fabrics;
3
4namespace Doc.LAMA0231.Fixed;
5
6internal class OrderService
7{
8 public void PlaceOrder( string product, int quantity ) { }
9
10 public void CancelOrder( int orderId ) { }
11
12 // Fixed: a type fabric can be nested in a run-time class, and it amends the containing type.
13 private class Fabric : TypeFabric
14 {
15 public override void AmendType( ITypeAmender amender )
16 {
17 amender.SelectMany( t => t.Methods ).AddAspect<LogAttribute>();
18 }
19 }
20}
21
1using System;
2using Metalama.Framework.Aspects;
3using Metalama.Framework.Fabrics;
4
5namespace Doc.LAMA0231.Fixed;
6
7
8#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
9
10internal class OrderService
11{
12 public void PlaceOrder(string product, int quantity)
13 {
14 Console.WriteLine("Executing OrderService.PlaceOrder(string, int).");
15 }
16 public void CancelOrder(int orderId)
17 {
18 Console.WriteLine("Executing OrderService.CancelOrder(int).");
19 }
20 // Fixed: a type fabric can be nested in a run-time class, and it amends the containing type.
21
22#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
23
24
25 private class Fabric : TypeFabric
26 {
27 public override void AmendType(ITypeAmender amender) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
28 }
29
30#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
31
32
33}
34
35#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
36
37
38