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:
- CompilationAspect
- ConstructorAspect
- EventAspect
- FieldAspect
- FieldOrPropertyAspect
- MethodAspect
- ParameterAspect
- PropertyAspect
- TypeAspect
- TypeParameterAspect
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.