| Severity | Error |
| Reported by | Metalama.Framework |
| Message | The type fabric '<Fabric>' cannot be nested in a compile-time type. |
Cause
A type fabric is a class derived from TypeFabric and nested in the type that it amends. Fabrics add aspects and advice to run-time code, so the containing type must be a run-time type.
Metalama reports LAMA0260 when a type fabric is nested in a type whose scope is compile-time, that is, a type marked with CompileTimeAttribute or RunTimeOrCompileTimeAttribute, or a type that's compile-time for another reason, such as an aspect class.
In the following example, PriceCalculator is marked with [RunTimeOrCompileTime] and contains a type fabric that adds a logging aspect to its methods.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0260.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.LAMA0260.Error;
5
6[RunTimeOrCompileTime]
7internal class PriceCalculator
8{
9 public decimal ApplyDiscount( decimal price, decimal rate ) => price * (1 - rate);
10
11 public decimal AddTax( decimal price, decimal rate ) => price * (1 + rate);
12
13 // Error: a type fabric cannot be nested in a run-time-or-compile-time type.
Error LAMA0260: The type fabric 'PriceCalculator.Fabric' cannot be nested in a compile-time type.
14 private class Fabric : TypeFabric
15 {
16 public override void AmendType( ITypeAmender amender )
17 {
18 amender.SelectMany( t => t.Methods ).AddAspect<LogAttribute>();
19 }
20 }
21}
22
Resolution
Do one of the following:
- If the type doesn't need to be used at compile time, remove the [CompileTime] or [RunTimeOrCompileTime] attribute so that the type becomes a run-time type, as in the following example.
- If the type must stay compile-time, remove the type fabric: a fabric can't amend compile-time code.
1using Metalama.Framework.Aspects;
2using System;
3
4namespace Doc.LAMA0260.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.LAMA0260.Fixed;
5
6// Fixed: the class no longer has the [RunTimeOrCompileTime] attribute, so it's a run-time type.
7internal class PriceCalculator
8{
9 public decimal ApplyDiscount( decimal price, decimal rate ) => price * (1 - rate);
10
11 public decimal AddTax( decimal price, decimal rate ) => price * (1 + rate);
12
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.LAMA0260.Fixed;
6
7// Fixed: the class no longer has the [RunTimeOrCompileTime] attribute, so it's a run-time type.
8
9#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
10
11
12internal class PriceCalculator
13{
14 public decimal ApplyDiscount(decimal price, decimal rate)
15 {
16 Console.WriteLine("Executing PriceCalculator.ApplyDiscount(decimal, decimal).");
17 return price * (1 - rate);
18 }
19
20 public decimal AddTax(decimal price, decimal rate)
21 {
22 Console.WriteLine("Executing PriceCalculator.AddTax(decimal, decimal).");
23 return price * (1 + rate);
24 }
25
26
27#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
28
29 private class Fabric : TypeFabric
30 {
31 public override void AmendType(ITypeAmender amender) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
32 }
33
34#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
35
36
37}
38
39#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
40
41
42