| 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
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
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