Announcing .NET 7 Preview 2 – The New, ‘New’ Experience

Angelos Petropoulos

Today, we are glad to release .NET 7 Preview 2. The second preview of .NET 7 includes enhancements to RegEx source generators, progress moving NativeAOT from experimental status into the runtime, and a major set of improvements to the “dotnet new” CLI experience. The bits are available for you to grab right now and start experimenting with new features like:

  • Build a specialized RegEx pattern matching engine using source generators at compile-time rather than slower methods at runtime.
  • Take advantage of SDK improvements that provide an entirely new, streamlined tab completion experience to explore templates and parameters when running dotnet new.
  • Don’t trim your excitement, just your apps in preparation to try out NativeAOT with your own innovative solutions.

EF7 preview 2 was also released and is available on NuGet. You can also read what’s new in ASP.NET Core Preview 2.

You can download .NET 7 Preview 2, for Windows, macOS, and Linux.

We recommend you use the preview channel builds if you want to try .NET 7 with Visual Studio family products. Visual Studio for Mac support for .NET 7 previews isn’t available yet but is coming soon.

Preview 2

The following features are now available in the Preview 2 release.

Introducing the new Regex Source Generator

https://github.com/dotnet/runtime/issues/44676

Have you ever wished you had all of the great benefits that come from having a specialized Regex engine that is optimized for your particular pattern, without the overhead of building this engine at runtime?

We are excited to announce the new Regex Source Generator which was included in Preview 1. It brings all of the performance benefits from our compiled engine without the startup cost, and it has additional benefits, like providing a great debugging experience as well as being trimming-friendly. If your pattern is known at compile-time, then the new regex source generator is the way to go.

In order to start using it, you only need to turn the containing type into a partial one, and declare a new partial method with the RegexGenerator attribute that will return the optimized Regex object, and that’s it! The source generator will fill the implementation of that method for you, and will get updated automatically as you make changes to your pattern or to the additional options that you pass in. Here is an example:

Before

public class Foo
{
  public Regex regex = new Regex(@"abc|def", RegexOptions.IgnoreCase);

  public bool Bar(string input)
  {
    bool isMatch = regex.IsMatch(input);
    // ..
  }
}

After

public partial class Foo  // <-- Make the class a partial class
{
  [RegexGenerator(@"abc|def", RegexOptions.IgnoreCase)] // <-- Add the RegexGenerator attribute and pass in your pattern and options
  public static partial Regex MyRegex(); //  <-- Declare the partial method, which will be implemented by the source generator

  public bool Bar(string input)
  {
    bool isMatch = MyRegex().IsMatch(input); // <-- Use the generated engine by invoking the partial method.
    // ..
  }
}

And that’s it. Please try it out and let us know if you have any feedback.

CodeGen

Community PRs (Many thanks to JIT community contributors!!)

From @sandreenko

From @SingleAccretion

From @Wraith2

Dynamic PGO

Arm64

General Optimizations

Observability

static Meter s_meter = new Meter("MyLibrary.Queues", "1.0.0");
static UpDownCounter<int> s_queueSize = s_meter.CreateUpDownCounter<int>("Queue-Size");
static ObservableUpDownCounter<int> s_pullQueueSize = s_meter.CreateObservableUpDownCounter<int>("Queue-Size", () => s_pullQueueSize);

...

s_queueSize.Add(10);
s_queueSize.Add(-2);

Logging source generator improvements

SDK Improvements

[Epic] New CLI parser + tab completion #2191

For 7.0.100-preview2, the dotnet new command has been given a more consistent and intuitive interface for many of the subcommands that users already use. In addition, support for tab completion of template options and arguments has been massively updated, now giving rapid feedback on valid arguments and options as the user types.

Here’s the new help output as an example:

❯ dotnet new --help
Description:
  Template Instantiation Commands for .NET CLI.

Usage:
  dotnet new [<template-short-name> [<template-args>...]] [options]
  dotnet new [command] [options]

Arguments:
  <template-short-name>  A short name of the template to create.
  <template-args>        Template specific options to use.

Options:
  -?, -h, --help  Show command line help.

Commands:
  install <package>       Installs a template package.
  uninstall <package>     Uninstalls a template package.
  update                  Checks the currently installed template packages for update, and install the updates.
  search <template-name>  Searches for the templates on NuGet.org.
  list <template-name>    Lists templates containing the specified template name. If no name is specified, lists all templates.

New Command Names

Specifically, all of the commands in this help output no longer have the -- prefix that they do today. This is more in line with what users expect from subcommands in a CLI application. The old versions (--install, etc) are still available to prevent breaking user scripts, but we hope to add obsoletion warnings to those commands in the future to encourage migration.

Tab Completion

The dotnet CLI has supported tab completion for quite a while on popular shells like PowerShell, bash, zsh, and fish (for instructions on how to enable that, see How to enable TAB completion for the .NET CLI). It’s up to individual dotnet commands to implement meaningful completions, however. For .NET 7, the new command learned how to provide tab completion for

  • Available template names (in dotnet new <template-short-name>)
❯ dotnet new angular
angular              grpc                 razor                viewstart            worker               -h
blazorserver         mstest               razorclasslib        web                  wpf                  /?
blazorwasm           mvc                  razorcomponent       webapi               wpfcustomcontrollib  /h
classlib             nugetconfig          react                webapp               wpflib               install
console              nunit                reactredux           webconfig            wpfusercontrollib    list
editorconfig         nunit-test           sln                  winforms             xunit                search
gitignore            page                 tool-manifest        winformscontrollib   --help               uninstall
globaljson           proto                viewimports          winformslib          -?                   update
  • Template options (the list of template options in the web template)
❯ dotnet new web --dry-run
--dry-run                  --language                 --output                   -lang
--exclude-launch-settings  --name                     --type                     -n
--force                    --no-https                 -?                         -o
--framework                --no-restore               -f                         /?
--help                     --no-update-check          -h                         /h
  • Allowed values for those template options (choice values on an choice template argument)
❯ dotnet new blazorserver --auth Individual
Individual     IndividualB2C  MultiOrg       None           SingleOrg      Windows

There are a few known gaps in completion – for example, --language doesn’t suggest installed language values.

Future work

In future previews, we plan to continue filling gaps left by this transition, as well as make enabling completions either automatic or as simple as a single command that the user can execute. We hope that this will make improvements in tab completion across the entire dotnet CLI more broadly used by the community!

What’s next

dotnet new users – go enable tab completion and try it for your templating use! Template authors – try out tab completion for the options on your templates and make sure you’re delivering the experiences you want your users to have. Everyone – raise any issues you find on the dotnet/templating repo and help us make .NET 7 the best release for dotnet new ever!

NativeAOT Update

We previously announced that we’re moving the NativeAOT project out of experimental status and into mainline development in .NET 7. Over the past few months, we’ve been heads down doing the coding to move NativeAOT out of the experimental dotnet/runtimelab repo and into the dotnet/runtime repo.

That work has now been completed, but we have yet to add first-class support in the dotnet SDK for publishing projects with NativeAOT. We hope to have that work done shortly, so you can try out NativeAOT with your apps. In the meantime, please try trimming your app and ensure there are no trim warnings. Trimming is a requirement of NativeAOT. If you own any libraries there are also instructions for preparing libraries for trimming.

Targeting .NET 7

To target .NET 7, you need to use a .NET 7 Target Framework Moniker (TFM) in your project file. For example:

<TargetFramework>net7.0</TargetFramework>

The full set of .NET 7 TFMs, including operating-specific ones follows.

  • net7.0
  • net7.0-android
  • net7.0-ios
  • net7.0-maccatalyst
  • net7.0-macos
  • net7.0-tvos
  • net7.0-windows

We expect that upgrading from .NET 6 to .NET 7 should be straightforward. Please report any breaking changes that you discover in the process of testing existing apps with .NET 7.

Support

.NET 7 is a Current release, meaning it will receive free support and patches for 18 months from the release date. It’s important to note that the quality of all releases is the same. The only difference is the length of support. For more about .NET support policies, see the .NET and .NET Core official support policy.

Breaking changes

You can find the most recent list of breaking changes in .NET 7 by reading the Breaking changes in .NET 7 document. It lists breaking changes by area and release with links to detailed explanations.

To see what breaking changes are proposed but still under review, follow the Proposed .NET Breaking Changes GitHub issue.

Roadmaps

Releases of .NET include products, libraries, runtime, and tooling, and represent a collaboration across multiple teams inside and outside Microsoft. You can learn more about these areas by reading the product roadmaps:

Closing

We appreciate and thank you for your all your support and contributions to .NET. Please give .NET 7 Preview 2 a try and tell us what you think!

14 comments

Comments are closed. Login to edit/delete your existing comments

  • Dan Balasescu

    Thanks all! Any chance to see GC regions in the next preview?

  • Trust Mutemasango

    What happened with porting WCF to .Net 6 and possibly 7

  • Maximilien Noal

    The typical desktop app that I write these days uses AvaloniaUI and Serilog, I wonder how much are they compatible with Trimming and NativeAOT if I jump to .NET 7 Preview 2 ?

  • Nathan Ferreira

    Still no ETA for java interop implementation in .NET? Maybe when release .NET 32.0? .NET promised this so many of us are waiting for that interop support.

  • Louis Lecailliez

    I just tried the Regex source generator on a console project that is regex intensive. Execution time of a specific task went from ~11.3 seconds to ~2.2 seconds, which is really impressive. However, the fact only strings known at compile time is too restrictive : another part of the project use really long regexes that are constructed at runtime not because that aren’t known at compile time but because building them with a fluent API makes them really easy to understand and maintain.

    Asking for a real macro system is probably too much, but in the mean time we are in a weird spot where to reach max performance one would have to compile and execute a part of the project to generate code that will use the regex source generator for few regexes that are too long to write by hand.

    • Stephen Toub

      Execution time of a specific task went from ~11.3 seconds to ~2.2 seconds, which is really impressive.

      How are you constructing the Regex taking 11.3 seconds? Did you specify RegexOptions.Compiled? There shouldn’t be such a massive difference in throughput in .NET 7 between RegexOptions.Compiled and the source generator; other than one emitting IL and the other emitting C#, they share 99% of the same structure and optimizations. The primary benefits of the source generator over RegexOptions.Compiled are startup performance, support for AOT, linkability, debugability, and understandability. There are a handful of throughput benefits as well, but currently all relatively minor.

      • Black Elijah (BT-AI/ETW2-PAI)

        @Stephen Toub, Just out of curiosity, if I write a source generator that emits code with the

        [RegexGenerator(...)] 

        attribute, will the RegexGenerator source generator still process the code that was emitted by my source generator? It seems like there’s potential for an infinite loop there.

    • Black Elijah (BT-AI/ETW2-PAI)

      I suppose you could use the new C# 6 Source Generator feature to run the fluent API code and emit methods with the

      [RegexGenerator(...)] 

      attribute 🙂

  • Dan Friedman

    With NativeAOT requiring trimming, will trimming be supported for non-self-contained apps?

    • Andy GockeMicrosoft employee

      All NativeAOT apps are self-contained, so it’s not clear to me why that would be relevant.

  • Jim Foye

    What’s the comment moderation policy?

    I’m asking because I believe my comment was deleted.