MetalamaConceptual documentationCreating aspectsAdvising a single type with a fabric
Open sandboxFocusImprove this doc

Advising a single type with a fabric

Instead of using aspects, you can advise the current type using a type fabric. A type fabric is a compile-time nested class that functions as a type-level aspect added to the target type.

To advise a type using a type fabric, follow these steps:

  1. Create a nested type derived from the TypeFabric class.

    Note

    For optimal design-time performance and usability, we recommend implementing type fabrics in a separate file and marking the containing type as partial.

  2. Override the AmendType method.

  3. Utilize the methods exposed on the amender.Advice property. To use this feature, you must be familiar with advanced aspects. For more details, refer to Transforming code.

  4. Optionally, you can add declarative advice, such as member introductions, to your type fabrics. For more information, see Introducing members.

Note

Type fabrics are always executed first, before any aspect. As a result, they can only add advice to members defined in the source code. If you need to add advice to members introduced by an aspect, you will need to use a helper aspect and order it after the aspects that provide the members you wish to advise.

Example

The following example demonstrates how to create a type fabric that introduces ten methods to the target type.

Source Code
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Fabrics;
3
4namespace Doc.AdvisingTypeFabric
5{
6    internal class MyClass


7    {
8        private class Fabric : TypeFabric


9        {
10            [Template]
11            public int MethodTemplate( [CompileTime] int index )
12            {
13                return index;


































14            }
15
16            public override void AmendType( ITypeAmender amender )
17            {
18                for ( var i = 0; i < 10; i++ )
19                {
20                    amender.Advice.IntroduceMethod(



21                        amender.Type,
22                        nameof(this.MethodTemplate),
23                        args: new { index = i },
24                        buildMethod: m => m.Name = "Method" + i );
25                }
26            }




27        }




28    }
29}
Transformed Code
1using Metalama.Framework.Aspects;
2using Metalama.Framework.Fabrics;
3
4namespace Doc.AdvisingTypeFabric
5{
6
7#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
8    internal class MyClass
9    {
10
11#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
12        private class Fabric : TypeFabric
13        {
14            [Template]
15            public int MethodTemplate([CompileTime] int index) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
16
17
18            public override void AmendType(ITypeAmender amender) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
19
20        }
21
22#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
23
24        public int Method0()
25        {
26            return 0;
27        }
28
29        public int Method1()
30        {
31            return 1;
32        }
33
34        public int Method2()
35        {
36            return 2;
37        }
38
39        public int Method3()
40        {
41            return 3;
42        }
43
44        public int Method4()
45        {
46            return 4;
47        }
48
49        public int Method5()
50        {
51            return 5;
52        }
53
54        public int Method6()
55        {
56            return 6;
57        }
58
59        public int Method7()
60        {
61            return 7;
62        }




63
64        public int Method8()
65        {
66            return 8;
67        }
68
69        public int Method9()
70        {
71            return 9;
72        }
73    }
74
75#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
76
77}