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 works as a type-level aspect added to the target type.
To advise a type using a type fabric:
Create a nested type derived from the TypeFabric class.
Note
For design-time performance and usability, we recommend implementing type fabrics in a separate file, and marking the containing type as
partial
.Override the AmendType method.
Use the methods exposed on the amender.Advice property. You must be familiar with advanced aspects before you can use this feature. For details, see Transforming code.
Optionally add declarative advice, such as member introductions, to your type fabrics. See Introducing members for details.
Note
Type fabrics are always executed first, before any aspect. Therefore, they can only add advice to members defined in source code. If you need to add advice to members that are introduced by an aspect, you need to use a helper aspect and order it after the aspects that provide the members that you want to advise.
Example
The following example demonstrates creating a type fabric that introduces ten methods to the target type.
using Metalama.Framework.Aspects;
using Metalama.Framework.Fabrics;
namespace Doc.AdvisingTypeFabric
{
internal class MyClass
{
private class Fabric : TypeFabric
{
[Template]
public int MethodTemplate( [CompileTime] int index )
{
return index;
}
public override void AmendType( ITypeAmender amender )
{
for ( var i = 0; i < 10; i++ )
{
amender.Advices.IntroduceMethod(
amender.Type,
nameof(this.MethodTemplate),
args: new { index = i },
buildMethod: m => m.Name = "Method" + i );
}
}
}
}
}
using Metalama.Framework.Aspects;
using Metalama.Framework.Fabrics;
namespace Doc.AdvisingTypeFabric
{
#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
internal class MyClass
{
#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
private class Fabric : TypeFabric
{
[Template]
public int MethodTemplate([CompileTime] int index) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
public override void AmendType(ITypeAmender amender) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
}
#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
public int Method0()
{
return 0;
}
public int Method1()
{
return 1;
}
public int Method2()
{
return 2;
}
public int Method3()
{
return 3;
}
public int Method4()
{
return 4;
}
public int Method5()
{
return 5;
}
public int Method6()
{
return 6;
}
public int Method7()
{
return 7;
}
public int Method8()
{
return 8;
}
public int Method9()
{
return 9;
}
}
#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
}