Metalama 2024.2 Generally Available: Class Introductions, Observability, and Much More
Metalama 2024.2 is now Generally Available. It is the first release to allow the automatic implementation of any code pattern. Its most-wanted features: you can now generate new classes and override or introduce constructors. This release also adds a robust ready-made implementation of INotifyPropertyChanged
through the Metalama.Patterns.Observability
package, supporting complex expressions and child objects. The Metalama.Patterns.Wpf
package automatically implements dependency properties and commands. To enable these new features, we’ve made dozens of improvements across various aspects.
Generating whole classes
You asked, and we listened!
In previous versions, Metalama could generate members of existing types, but introducing new types wasn’t possible. With Metalama 2024.2, you can now build new classes (both top-level and nested) from scratch!
To illustrate this, here is an incomplete implementation of the Builder pattern:
public class BuilderAttribute : TypeAspect
{
public override void BuildAspect( IAspectBuilder<INamedType> builder )
{
base.BuildAspect( builder );
// Introduce a nested type.
var nestedType = builder.IntroduceClass( "Builder" );
// Introduce properties.
var properties =
builder.Target.Properties.Where(
p => p.Writeability != Writeability.None && !p.IsStatic );
foreach ( var property in properties )
{
nestedType.IntroduceAutomaticProperty(
property.Name,
property.Type );
}
}
}
For a complete implementation of the Builder pattern, see Introducing types in the reference documentation. You might also be interested in our implementations of the Memento and Enum View-Model patterns.
Observability (INotifyPropertyChanged)
The second highlight of Metalama 2024.2 is our Observable aspect, implementing the INotifyPropertyChanged
interface. This implementation stands out by supporting complex properties and child objects, i.e., properties that depend on properties of properties, recursively.
[Observable]
public sealed class PersonViewModel
{
public Person Person { get; set; }
public PersonViewModel( Person model )
{
this.Person = model;
}
public string? FirstName => this.Person.FirstName;
public string? LastName => this.Person.LastName;
public string FullName => $"{this.FirstName} {this.LastName}";
}
Our Observable aspect is designed for safety: it will warn you if it doesn’t understand all dependencies in your code. Best of all, it is completely open-source.
Metalama.Patterns.Wpf
This package (formerly named Metalama.Patterns.Xaml
) automatically implements dependency properties and commands through the DependencyProperty and Command aspects.
They integrate with Observable and Metalama Code Contracts to minimize boilerplate code.
[Observable]
public class MyWindow : Window
{
[DependencyProperty]
[Range(0, 10)]
public int Counter { get; private set; }
public bool CanExecuteIncrement => this.Counter < 10;
public bool CanExecuteDecrement => this.Counter > 0;
[Command]
public void Increment()
{
this.Counter++;
}
[Command]
public void Decrement()
{
this.Counter--;
}
}
Performance improvements
We continue to enhance performance in Metalama 2024.2. This time, we’ve optimized fabrics to run object queries in parallel and redesigned the reference validation facility used by Metalama.Extensions.Architecture
to avoid redundant verifications.
Dozens of other improvements
Beyond the spotlight features, Metalama 2024.2 includes dozens of improvements in the following areas:
- The new package
Metalama.Patterns.Immutability
materializes the concept of immutability and is used by theMetalama.Patterns.Observability
package. - You can now introduce and override constructors.
- The T# language has been improved. You can:
- Use lambda statements and anonymous methods in templates—both in run-time and compile-time code.
- Dynamically build
switch
statements with SwitchStatementBuilder. - Evaluate a T# template into an
IStatement
with StatementFactory.FromTemplate.
- The
Metalama.Extensions.Architecture
and the underlying Fabric API have been revamped to improve performance and extensibility. There are breaking changes in the extensibility API. Metalama.Patterns.Contracts
now generate idiomatic code, fix some terminology issue, also with some breaking changes.- When suppressing warnings, you can now add a warning filter to suppress only warnings with specific arguments.
- The test framework is now integrated with DiffEngine.
- The quality and performance of code formatting have improved.
- When troubleshooting Metalama, it is now possible to enable and direct tracing to the build output using an environment variable.
Release notes and change log
For a list of all improvements, see the Metalama 2024.2 Release Notes. There are breaking changes!
For an even more detailed list of all changes, including bug fixes, see the change logs.
Remember that Metalama is source-available, so you can review every single commit.
Roadmap
With Metalama 2024.2, we feel we have implemented enough new features for this year and need to focus on quality and stability. Although we always fix customer-reported bugs as soon as possible, we have a growing backlog of less critical issues that we’ve neglected to make time for new features, and these will now get our attention.
During the rest of the summer, we will concentrate on fixing bugs, writing more examples, and perhaps implementing a few small features requested by the community. This work will be done in the 2024.2 branch.
As every year, starting in the autumn, we plan to work on .NET 9 and C# 13 support. The new .NET stack will be supported in Metalama 2025.0. Our goal is to release a preview of Metalama 2025.0 with support for .NET 9.0 within days after Microsoft announces its GA, to have an RC before the Christmas break, and to make Metalama 2025.0 generally available in the first days of 2025.
Conclusion
Metalama 2024.2 is an exciting release, the first to allow the implementation of virtually any pattern with Metalama. While writing documentation and examples for this release, I felt a strong craftsman’s pride. Metalama now (almost) completely realizes my initial vision. Its APIs are smooth, and we can give a positive answer to most user concerns.
With Metalama 2024.2, we made it!
We’re looking forward to your feedback. Don’t hesitate to reach out on GitHub or Slack with any problems or questions.
Happy meta-programming!