Open sandboxFocus

Class AspectQueryExtensions

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

Inheritance
AspectQueryExtensions
Namespace: Metalama.Framework.Aspects
Assembly: Metalama.Framework.dll
Syntax
[CompileTime]
public static class AspectQueryExtensions
Remarks

These extension methods are primarily used with fabrics (ProjectFabric, TypeFabric, etc.) to add aspects programmatically to selected declarations. In a ProjectFabric, use the amender parameter's query methods to select declarations, then call these methods to add aspects:

// In a ProjectFabric.AmendProject override
amender.SelectMany(p => p.Types)
.SelectMany(t => t.Methods.Where(m => m.Accessibility == Accessibility.Public))
.AddAspectIfEligible<LoggingAspect>();

They can also be used with Outbound to add child aspects from within the BuildAspect(IAspectBuilder<T>) method:

// In an aspect's BuildAspect method
builder.Outbound.SelectMany(t => t.Methods).AddAspect<LoggingAspect>();

AddAspect vs AddAspectIfEligible: AddAspect<TAspect>(IQuery<IDeclaration>) throws an exception if the target is ineligible, while AddAspectIfEligible<TAspect>(IQuery<IDeclaration>, EligibleScenarios) silently skips ineligible targets. For bulk operations in fabrics, AddAspectIfEligible<TAspect>(IQuery<IDeclaration>, EligibleScenarios) is generally recommended.

AddAspect vs RequireAspect: AddAspect<TAspect>(IQuery<IDeclaration>) always creates a new aspect instance (existing instances become secondary). RequireAspect<TAspect>(IQuery<IDeclaration>) only adds an instance if the aspect doesn't already exist on the target.

Child aspect ordering: When adding child aspects from an aspect, the child aspect class must be ordered after the parent aspect. The child must be listed before the parent in the AspectOrderAttribute definition.

Precedence: Aspects added manually as custom attributes take precedence over aspects added programmatically. When the same aspect type is applied multiple times, the primary instance executes and secondary instances are available via SecondaryInstances.

Methods

Name Description
AddAspectIfEligible<TAspect>(IQuery<IDeclaration>, EligibleScenarios)

Adds an aspect to the current set of declarations using the default constructor of the aspect type. This method does not verify the eligibility of the declaration for the aspect unless you specify the eligibility parameter. This overload creates a new instance of the aspect class for each eligible target declaration.

AddAspectIfEligible<TDeclaration>(IQuery<TDeclaration>, Type, Func<TDeclaration, IAspect>, EligibleScenarios)

Adds an aspect to the current set of declarations but only if the aspect is eligible for the declaration. This overload is non-generic.

AddAspectIfEligible<TDeclaration, TAspect>(IQuery<TDeclaration>, Func<TDeclaration, TAspect>, EligibleScenarios)

Adds an aspect to the current set of declarations but only if the aspect is eligible for the declaration.

AddAspectIfEligible<TDeclaration, TTag>(ITaggedQuery<TDeclaration, TTag>, Type, Func<TDeclaration, TTag, IAspect>, EligibleScenarios)

Adds an aspect to the current set of declarations but only if the aspect is eligible for the declaration. This overload is non-generic.

AddAspectIfEligible<TDeclaration, TTag, TAspect>(ITaggedQuery<TDeclaration, TTag>, Func<TDeclaration, TTag, TAspect>, EligibleScenarios)

Adds an aspect to the current set of declarations but only if the aspect is eligible for the declaration.

AddAspect<TAspect>(IQuery<IDeclaration>)

Adds an aspect to the current set of declarations or throws an exception if the aspect is not eligible for the aspect. This overload creates a new instance of the aspect class for each target declaration.

AddAspect<TDeclaration>(IQuery<TDeclaration>, Type, Func<TDeclaration, IAspect>)

Adds a aspect to the current set of declarations or throws an exception if the aspect is not eligible for the aspect. This overload is non-generic.

AddAspect<TDeclaration, TAspect>(IQuery<TDeclaration>, Func<TDeclaration, TAspect>)

Adds an aspect to the current set of declarations or throws an exception if the aspect is not eligible for the aspect.

AddAspect<TDeclaration, TTag>(ITaggedQuery<TDeclaration, TTag>, Type, Func<TDeclaration, TTag, IAspect>)

Adds a aspect to the current set of declarations or throws an exception if the aspect is not eligible for the aspect. This overload is non-generic.

AddAspect<TDeclaration, TTag, TAspect>(ITaggedQuery<TDeclaration, TTag>, Func<TDeclaration, TTag, TAspect>)

Adds an aspect to the current set of declarations or throws an exception if the aspect is not eligible for the aspect.

RequireAspect<TAspect>(IQuery<IDeclaration>)

Requires an instance of a specified aspect type to be present on a specified declaration. If the aspect is not present, this method adds a new instance of the aspect using the default aspect constructor.

See Also