Open sandboxFocusImprove this doc

Namespace Metalama.Framework.Aspects

This namespace enables you to build aspects. Aspects represent an algorithmic approach to code transformation or validation.

For instance, tasks such as adding logging to a method or implementing INotifyPropertyChanged can largely be expressed as an algorithm and, therefore, implemented as an aspect.

Conceptual Documentation

Refer to Creating aspects for more information.

Overview

To create an aspect, you need to create a class that derives from Attribute and implement the IAspect<T> interface. Alternatively, you can use one of the following classes, which already derive from Attribute, have the appropriate AttributeUsageAttribute, and implement the IAspect<T> interface:

Class Diagrams

Aspect builders

classDiagram

    class IAspect {
        BuildAspect(IAspectBuilder)
        BuildEligibility(IEligibilityBuilder)
    }

    class IAspectBuilder {
        SkipAspect()
        TargetDeclaration
    }

    class IAdviser {
        Target
        With(declaration)
    }


    class ScopedDiagnosticSink {
        Report(...)
        Suppress(...)
        Suggest(...)
    }

    class AdviserExtensions {
        <<static>>
        Override(...)
        Introduce*(...)
        ImplementInterface(...)
        AddContract(...)
        AddInitializer(...)
    }

    class IAspectReceiver {
        Select(...)
        SelectMany(...)
        Where(...)
        AddAspect(...)
        AddAspectIfEligible(...)
        Validate(...)
        ValidateInboundReferences(...)
        ReportDiagnostic(...)
        SuppressDiagnostic(...)
        SuggestCodeFix(...)
    }

    IAspect --> IAspectBuilder : BuildAspect() receives
    IAspectBuilder --|> IAdviser : inherits 
    IAspectBuilder --> ScopedDiagnosticSink : exposes
    IAspectBuilder --> IAspectReceiver : exposes
    AdviserExtensions --> IAdviser : provides extension\nmethods

Scope custom attributes

classDiagram

ScopeAttribute <|-- CompileTimeAttribute  : derives from
ScopeAttribute <|-- RunTimeOrCompileTimeAttribute  : derives from


Advice and template attributes

classDiagram

IAdviceAttribute <|-- ITemplateAttribute : derives from
IAdviceAttribute <| -- DeclarativeAdviceAttribute : derives from
ITemplateAttribute <|-- TemplateAttribute  : derives from
DeclarativeAdviceAttribute <|-- IntroduceAttribute  : derives from
DeclarativeAdviceAttribute <|-- IntroduceDependencyAttribute  : derives from
ITemplateAttribute <|-- InterfaceMemberAttribute  : derives from

IAspectInstance, IAspectPredecessor

The IAspectPredecessor facility allows aspects to access their parent (i.e. the artifact that created them): a parent aspect, a fabric, or a custom attribute.

classDiagram

   class AspectPredecessorKind {
       <<enum>>
       Attribute
       ChildAspect
       RequiredAspect
       Inherited
       Fabric
   }

    class IAspect {
        BuildAspect(IAspectBuilder)
    }

    class IAspectBuilder {
        AspectInstance
    }

    class  IAspectState {

    }

    class IAttribute {
        ContainingDeclaration
        Type
        Constructor
        ConstructorArguments
        NamedArguments
    }

    IAspectInstance <-- IAspectBuilder : exposes

    IAspectBuilder <-- IAspect : receives

    IAspectPredecessor <|-- IAttribute : derives from

    IAspectPredecessor <|-- IFabricInstance : derives from

    class IAspectPredecessor {

    }

    class IFabricInstance {
        Fabric
        TargetDeclaration
    }

   class IAspectInstance {
       Aspect
       AspectClass
       IsSkipped
       Procecessors
       SecondaryInstances
       State
       TargetDeclaration
   }

    IAspectState <-- IAspectInstance : exposes
    IAspect <-- IAspectInstance : exposes
    IAspectPredecessor <|-- IAspectInstance : derives from
    IAspectState <-- IAspect : reads & writes

   IAspectInstance *-- AspectPredecessor : has

   class AspectPredecessor {
       Kind
       Instance
   }

   IAspectPredecessor <-- AspectPredecessor : exposes
   AspectPredecessorKind <-- AspectPredecessor : has

Namespace members

Classes

AdviserExtensions

Aspect

A base class for aspects that can be applied as custom attributes. Derive from this class or a specialized aspect base class to create aspects that transform or validate code at compile time.

AspectOrderAttribute

Assembly-level custom attribute that specifies the execution order of aspects or aspect layers. Define ordering relationships using this attribute to control how aspects compose with each other.

AspectPredecessorExtensions

Extension methods for IAspectPredecessor.

AspectQueryExtensions

Extension methods for IQuery<TDeclaration> and ITaggedQuery<TDeclaration, TTag> that provide methods to add aspects to declarations selected through queries.

CompilationAspect

A base class for aspects that target the compilation level, applied using assembly-level custom attributes (e.g., [assembly: MyAspect]).

CompileTimeAttribute

Attribute that means that the target declaration (and all children declarations) can only be called from compile-time code and, therefore, not from run-time code. See RunTimeOrCompileTimeAttribute for declarations that can be called both from compile-time and run-time code.

CompiledTemplateAttribute

Internal attribute added by Metalama during compilation to preserve the original characteristics of templates.

ConstructorAspect

A base class for aspects that target constructor declarations.

ContractAspect

A base aspect that can validate or change the value of fields, properties, indexers, and parameters. Contracts are typically used to validate input parameters (preconditions), output parameters and return values (postconditions), or to normalize values. For ready-made contract implementations, see the Metalama.Patterns.Contracts package.

DeclarativeAdviceAttribute

A base class for attributes that define declarative advice on aspect members. These attributes enable aspects to transform code without requiring explicit calls in BuildAspect(IAspectBuilder<T>).

EditorExperienceAttribute

Configures how an aspect is presented in the IDE's code refactoring menu, including options for applying the aspect as a live template or as a custom attribute. This attribute is applied to aspect classes to control their editor experience.

EditorExperienceOptions

Represents the compile-time options controlling how an aspect is suggested in the IDE's code refactoring menu.

EventAspect

A base class for aspects that target event declarations.

ExcludeAspectAttribute

Custom attribute that, when applied to a declaration, prevents specified aspect types from being applied to this declaration and all its members, except when the aspect is explicitly added as a custom attribute on the declaration.

FieldAspect

A base class for aspects that target field declarations.

FieldOrPropertyAspect

A base class for aspects that target both field and property declarations uniformly.

ForcedGenericRunTimeOrCompileTimeAttribute

Attribute that means that the target declaration (and all children declarations) can be called both from compile-time and run-time code, even if the generic type arguments are not run-time-or-compile-time.

FrameworkDiagnosticDescriptors

Contains diagnostic descriptors used internally by the Metalama Framework. This class is reserved for internal use.

InheritableAttribute

Custom attribute that, when applied to an aspect class, causes all instances of this aspect to be inherited by derived declarations. The aspect's BuildAspect(IAspectBuilder<T>) method is invoked not only for the direct target declaration but also for all derived declarations.

InterfaceMemberAttribute

Marks a member in an aspect class as a template for implementing an interface member.

IntroduceAttribute

Marks a member in an aspect class to be introduced (added) to the target type.

InvalidAdviceParametersException

An exception thrown by IAdviceFactory methods when the parameters passed to an advice method are invalid or incompatible with the target declaration.

InvalidTemplateSignatureException

An exception thrown by IAdviceFactory when compile-time code attempts to add a template to a target declaration and the template signature is not compatible with the advice and the target declaration.

LayersAttribute

Custom attribute that, when applied to an aspect class, means that this aspect class uses several layers, and defines the name and the order of execution of these layers. In multi-aspect layers, the BuildAspect(IAspectBuilder<T>) method is called several times, once for each layer. The current layer is exposed in the Layer property.

MethodAspect

A base class for aspects that target method declarations.

OverrideEventAspect

A base aspect that overrides the implementation of an event by providing template methods for add, remove, and invoke operations.

OverrideFieldOrPropertyAspect

A base aspect that overrides the implementation of a field or property using T# template properties.

OverrideMethodAspect

A base class for aspects that override method implementations using T# templates.

ParameterAspect

A base class for aspects that target method, constructor, or indexer parameter declarations.

PropertyAspect

A base class for aspects that target property declarations.

RequireAspectWeaverAttribute

Binds an aspect class to a low-level weaver implementation built with Metalama.Framework.Sdk. When this attribute is applied to an aspect class, the BuildAspect(IAspectBuilder<T>) method is bypassed and the specified weaver handles all transformations instead.

RunTimeAttribute

Attribute that means that the target declaration (and all children declarations) can only be called from run-time code and, therefore, not from compile-time code. Code is run-time by default, so this attribute only makes sense on classes or interface that are run-time-only but derive a run-time-or-compile-time type. See RunTimeOrCompileTimeAttribute.

RunTimeOrCompileTimeAttribute

Attribute that means that the target declaration (and all children declarations) can be called both from compile-time and run-time code. See CompileTimeAttribute for declarations that cannot be called from run-time code.

ScopeAttribute

A base class for all custom attributes that influence the scope (compile-time or run-time) of the code or its role in an aspect.

TemplateAttribute

Marks a method, property, field, or event as a T# template that can be used to generate or transform code.

TemplateInvocation

Represents a delegate-like encapsulation of a template method invocation. This enables passing template calls as parameters to other templates, supporting advanced patterns like decorator composition.

ThisAttribute

When applied to a template method parameter, indicates that the introduced parameter should have the this modifier, making the introduced method an extension method.

TypeAspect

A base class for aspects that target type declarations (classes, structs, interfaces, delegates, and enums).

TypeParameterAspect

A base class for aspects that target generic type parameter declarations.

meta

The entry point for the T# template language, providing compile-time APIs to inspect and transform target code.

Structs

AspectPredecessor

Represents one link in the causality chain that led to an aspect being applied. Each predecessor describes what caused an aspect instance to be created (e.g., a custom attribute, a fabric, a parent aspect, or inheritance).

TemplateProvider

Wraps a template provider type or instance for use in auxiliary template invocation and advice factory methods.

Interfaces

IAdviser

An object that allows declarations to be advised (transformed) using extension methods from AdviserExtensions. This is the non-generic base interface; aspects typically use the generic IAdviser<T> variant.

IAdviser<T>

An object that allows declarations to be advised using one of the extension methods of the AdviserExtensions class.

IAspect

The base interface for all aspects. Aspects are compile-time components that transform, validate, or enhance code.

IAspectBuilder

Provides the context and operations for building an aspect in the BuildAspect(IAspectBuilder<T>) method. This is the primary API for implementing aspect behavior at compile time.

IAspectBuilder<TAspectTarget>

An object used by the BuildAspect(IAspectBuilder<T>) method of the aspect to provide advice, child aspects and validators, or report diagnostics. This is a strongly-typed variant of the IAspectBuilder interface.

IAspectClass

Represents the metadata and characteristics of an aspect class type, providing information about how the aspect is displayed, whether it's inheritable, and other type-level properties.

IAspectInstance

Represents an instance of an aspect. The instance of the IAspect itself is in the Aspect property.

IAspectPredecessor

Base interface for objects that can cause aspects to be added to a compilation, such as aspect instances and fabric instances. This interface tracks the chain of causality that led to an aspect being applied, accessible through the Predecessors property.

IAspectState

An empty interface that must be implemented by objects assigned to the AspectState property of the IAspectBuilder interface.

IAspect<T>

The generic base interface for all aspects, where the type parameter specifies the kind of code declaration the aspect can be applied to.

IConditionallyInheritableAspect

An interface that can be implemented by aspects that determine their inheritability dynamically based on aspect properties or the target declaration. When all the instances of the aspect class are unconditionally inheritable, use the InheritableAttribute instead.

IMetaTarget

Provides access to the target declaration being transformed by an aspect template. Access via meta.Target in template code.

IObjectReader

Provides read-only dictionary access to tags passed from the BuildAspect(IAspectBuilder<T>) method to templates. Accessible in templates via Tags.

ITemplateProvider

An interface that specifies that the type contains templates. Templates must be annotated with TemplateAttribute. To call auxiliary templates from a class implementing this interface, use the InvokeTemplate(string, ITemplateProvider?, object?) method.

Enums

AspectOrderDirection

Specifies the direction in which aspect types or aspect layers are ordered in AspectOrderAttribute. Choose between run-time execution order (outside-in) or compile-time application order (inside-out).

AspectPredecessorKind

Specifies how an aspect instance was created or added to a declaration. This determines the type of object in Instance.

ContractDirection

Specifies the direction of the data flow to which a contract applies. Contracts can validate or transform values at different points in the data flow: when values are received (input/preconditions), when values are returned (output/postconditions), or both.

InterfaceMemberOverrideStrategy

Determines how to handle conflicts when introducing an interface member via InterfaceMemberAttribute when a member with the same name already exists on the target type.

IntroductionScope

Determines the scope (static vs instance) of a member introduced by an aspect.

OverrideStrategy

Specifies how introduction advice should behave when a member with the same name or signature already exists in the target type.