Open sandboxFocusImprove this doc

LAMA0260: A type fabric can't be nested in a compile-time type

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

See also