Open sandboxFocusImprove this doc

LAMA0231: Only type fabrics can be nested in a run-time type

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
Source Code
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
Transformed Code
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

See also