Open sandboxFocusImprove this doc

LAMA0230: A compile-time class nested in a run-time type must be private

Severity Error
Reported by Metalama.Framework
Message The compile-time type '<Type>' must be private because it is nested in a run-time type.

Cause

A type fabric is a compile-time class nested in the type that it amends. Because the containing type is run-time only, Metalama moves the nested fabric out of it in the compile-time assembly. The fabric must be invisible to the run-time code so that nothing at run time can reference it.

Metalama reports LAMA0230 when a compile-time class nested in a run-time type has any accessibility other than private, for instance public or internal.

In the following example, the type fabric of OrderService is public.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0230.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.LAMA0230.Error;
5
6internal class OrderService
7{
8    public void PlaceOrder( string product, int quantity ) { }
9
10    public void CancelOrder( int orderId ) { }
11
12    // Error: a type fabric nested in a run-time class must be private.
    Error LAMA0230: The compile-time type 'OrderService.Fabric' must be private because it is nested in a run-time type.

13    public class Fabric : TypeFabric
14    {
15        public override void AmendType( ITypeAmender amender )
16        {
17            amender.SelectMany( t => t.Methods ).AddAspect<LogAttribute>();
18        }
19    }
20}
21

Resolution

Make the nested class private, as in the following example.

If the class isn't a type fabric, making it private isn't enough, because only type fabrics can be nested in a run-time type (see LAMA0231). Move it out of the containing type instead.

1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0230.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.LAMA0230.Fixed;
5
6internal class OrderService
7{



8    public void PlaceOrder( string product, int quantity ) { }
9
10    public void CancelOrder( int orderId ) { }








11
12    // Fixed: the type fabric is private.

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.LAMA0230.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: the type fabric is private.
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