Metalama Status Update, June 2024

by Gael Fraiteur on 28 Jun 2024

The main focus this month was completing the new Metalama 2024.2 release. We’re now just a couple of days away from the RC. The coolest addition this month is the ability to add top-level classes. The INotifyPropertyChanged and XAML aspects are now final. The introspection APIs and our LinqPad driver have been greatly improved.

Metalama 2024.0 and 2024.1

We published several bugfix releases for our supported versions. See the changelogs for details.

Following our product lifecycle and support guidelines, we announced on June 26th that Metalama 2024.0 came out of support. Metalama 2024.1 is our current stable release and will receive all bug fixes.

Progress on Metalama 2024.2

We’ve almost completed the development and testing work on Metalama 2024.2, which should be ready for RC next week. This new version should go GA by the end of July.

Type introduction

We finalized the work on class introduction. It’s now possible to create nested or top-level classes using an aspect. The API has been finalized and documented.

We are particularly proud of the Builder pattern example.

public class BuilderAttribute : TypeAspect
    public override void BuildAspect( IAspectBuilder<INamedType> builder )
        base.BuildAspect( builder );

        var builderType = builder
            .With( builder.Target.GetNamespace()! )
            .WithChildNamespace( "Builders" )
            .IntroduceClass( builder.Target.Name + "Builder" );

        var properties = builder.Target.Properties.Where( p => p.Writeability != Writeability.None && !p.IsStatic );

        foreach ( var property in properties )
                property.Type );

        // Details skipped for brevity.

Please refer to the online documentation for the complete code.

The Aspect Explorer, a tool window added by Visual Studio Tools for Metalama, now also displays the new top-level types introduced by an aspect. You can use this feature to preview the code of the generated type. This feature is still being stabilized.


We finished all planned work in Metalama.Patterns, our collection of open-source and professionally-built aspects.

  • We developed and published a new package Metalama.Patterns.Immutability to address the concept of immutable types. This concept is used in the [Observable] aspect. For details, see the reference documentation.
  • We finalized the design and documentation of Metalama.Patterns.Observability (implementing INotifyPropertyChanged) and Metalama.Patterns.Xaml (implementing commands and dependency properties). For details, see the reference documentation for Observability and XAML.
  • We finally addressed the naming issues with the number contracts in Metalama.Patterns.Contracts, where [LessThan] meant [LessThanOrEqual], [Positive] meant [NonNegative], and so on. Using these ambiguous contracts will result in a warning, which can be resolved by configuring the contracts in a fabric or by using the new, non-ambiguous [NonNegative], [NonPositive], [GreaterThanOrEqual], or [LessThanOrEqual]. For details, see the warning in the reference documentation.

Metalama.Framework.Workspaces and Metalama.LinqPad

We improved the Metalama.Framework.Workspaces API, which allows you to analyze projects from any code, and our LinqPad driver, which lets you query the code interactively.

The most important additions are the extension methods IDeclaration.GetInboundReferences() and IDeclaration.GetOutboundReferences allowing you to navigate references from or to a declaration. The new extension method INamedType.GetDerivedTypes() returns all types derived from the current named type within the current namespace.

It makes it extremely simple to verify source code from anywhere. The following snippet is a valid program that validates that the CodeQualityTalk.Abstractions namespace does not have dependencies on other non-system namespaces.

var workspace = Workspace.Load(args[0]);

    .Where(t => t.ContainingNamespace.FullName == "CodeQualityTalk.Abstractions")
    .SelectMany(t => t.GetOutboundReferences())
    .Where(r =>
        var ns = r.DestinationDeclaration.GetNamespace()!.FullName;
        return ns.StartsWith("CodeQualityTalk") && ns != "CodeQualityTalk.Abstractions";
        "The CodeQualityTalk.Abstractions namespace must not have dependencies on other namespaces.");

Other improvements

  • Aspect API: We added a new mechanism to pass tags: they can now be set using the new IAspectBuilder.Tags property from the BuildAspect method. This allows you to use tags in declarative advice, e.g. in [Introduce]d declarations.
  • Supportability: It is now possible to trace to the system console to ease troubleshooting on build agents. For details, see here.

The Timeless .NET Engineer

We continued publishing articles on the Timeless .NET Engineer blog and newsletters.

The goal of this series is to educate .NET developers about building robust and maintainable applications with clean code. Metalama is often mentioned as a possible solution, but none of the articles are product-centric.

This month, we released three articles:

Fast and Compact Structured Logging in C# Using String Interpolation 5 Practical Ways to Add Polly to Your C# Application [2024] Improving Your Team's Productivity Through Consistent Code Style

You can subscribe to this newsletter here.


Metalama 2024.2 is virtually completed and will be generally available by the end of July.

We don’t plan to start working on new features during the summer, but rather to focus on bug fixes and advocacy. And as every year during the summer, we will take some time off with our families. We plan to look at .NET 9.0 starting in September-October.


We can’t wait to release Metalama 2024.2. It’s a very cool version, and class introductions complete the vision I had back in 2020 when we started the project. You can now implement almost all patterns using Metalama—a dream I’ve been pursuing for 20 years, starting with PostSharp.

Happy meta-programming!

This article was first published on a under the title Metalama Status Update, June 2024.