DEV Community

Cover image for Everything New in .NET 9: The Ultimate Developer's Guide
ByteHide
ByteHide

Posted on • Edited on • Originally published at bytehide.com

Everything New in .NET 9: The Ultimate Developer's Guide

NET 9 is the latest iteration of Microsoft's cross-platform framework, designed to enhance modern application development with a focus on performance, security, and ease of use. This new version brings significant updates to its runtime, libraries, SDK, and related tools, as well as introducing advanced features for AI-based development, web, and mobile applications.

News in .NET 9

If you’re a developer looking to stay updated on all the latest features, this article breaks down every update in .NET 9 so you can make the most of this powerful platform.


1. .NET Runtime: Enhancing the Core of the Framework

The .NET 9 runtime has been optimized to deliver superior performance, improve the developer experience, and ensure applications are more efficient and robust. If you work with applications that demand high performance, these updates will be of particular interest.

News in .NET 9


1.1. Garbage Collector (GC) Optimization

The Garbage Collector in .NET 9 continues to evolve, with a focus on reducing pauses during collection in high-memory pressure scenarios. If you've ever dealt with micro-stutters in your applications when processing large volumes of data, this update is a relief.

For example, if you have an application that generates large amounts of temporary objects, the GC is now smarter about prioritizing what to collect and when.

How does this translate in practice?

Previously, in applications with massive lists, the GC could cause noticeable interruptions. Now, these interruptions are significantly reduced thanks to improved compaction and reduced costs associated with promoting objects between generations.

A look at the code:

var data = Enumerable.Range(1, 10_000_000).ToList();
Console.WriteLine($"Processing {data.Count} items...");
data = null; // Release memory.
GC.Collect(); // Manually invoke the collector.
Enter fullscreen mode Exit fullscreen mode

In this example, the process of freeing and collecting memory is faster in .NET 9, especially in systems with intensive memory usage.


1.2. ARM64 Support

With the growing adoption of ARM64 in servers and devices, .NET 9 introduces specific optimizations for this architecture. This not only improves performance on ARM devices like the Raspberry Pi but also on modern servers using ARM for greater energy efficiency.

What does this mean for you as a developer?

If your application runs in ARM64 environments like AWS Graviton, you'll notice faster runtimes and more efficient resource use. Additionally, improvements in JIT (Just-In-Time compilation) ensure your code adapts better to these architectures.

Console.WriteLine($"Running on: {System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture}");
Enter fullscreen mode Exit fullscreen mode

With this snippet, you can validate that your application is leveraging ARM64, ensuring you're maximizing performance on these platforms.


1.3. Application Initialization Improvements

The runtime now reduces startup times for .NET applications, crucial for microservices and containerized applications. Have you ever noticed applications taking a long time to start when part of an orchestrator like Kubernetes? In .NET 9, this issue is addressed with improvements that streamline initial loading.

Specific cases:

  • Applications can now load with more optimized configurations.
  • The time required to initialize assemblies has decreased significantly.
var app = WebApplication.CreateBuilder(args).Build();
app.MapGet("/", () => "Hello, .NET 9!");
app.Run();
Enter fullscreen mode Exit fullscreen mode

When you deploy this minimal application in a Docker container, you'll notice a significant reduction in startup times compared to previous versions.


1.4. Just-In-Time (JIT) Compilation Updates

The JIT in .NET 9 is not only faster but also smarter. Now, certain optimizations previously only available in Ahead-Of-Time (AOT) compilation are available in JIT, benefiting applications with complex execution flows.

JIT .NET 9

Developer advantages:

This means you can rely on your code being optimized at runtime without needing to change additional settings.

int Compute(int x, int y) => x * y + (x / y);
Console.WriteLine(Compute(10, 5));
Enter fullscreen mode Exit fullscreen mode

In .NET 9, these types of complex arithmetic operations take advantage of compiler-level optimizations, running faster and using fewer resources.


1.5. Enhanced Performance Diagnostics

When working with tools like dotnet-counters or dotnet-trace, organizing and securing logs across environments can become a significant challenge. While these tools provide deep insights, managing logs effectively often requires additional effort. A practical way to simplify this is by using solutions like ByteHide Logs, which centralizes all application logs into a single, secure platform. This allows you to filter and analyze logs effortlessly, while ensuring their protection with end-to-end encryption, addressing compliance and privacy requirements seamlessly.

dotnet-counters monitor --process-id <PID>
Enter fullscreen mode Exit fullscreen mode

Using these tools alongside runtime optimizations allows you to identify performance issues and solve them before they affect users.

2. .NET Libraries: More Tools and Flexibility

The libraries in .NET 9 have received a series of significant updates aimed at improving performance, security, and the developer experience. From new capabilities in JSON serialization to optimizations in LINQ and expanded support for modern cryptographic algorithms, these improvements are designed to make .NET development more powerful and efficient.


2.1. More Efficient JSON Serialization

JSON serialization has been a key focus in .NET 9, with System.Text.Json receiving enhancements that make working with structured data easier and faster. You can now serialize and deserialize record types and immutable structures without complex configurations.

Practical Example:

public record Product(string Name, decimal Price);

var product = new Product("Laptop", 1500.75m);
string json = JsonSerializer.Serialize(product);
Console.WriteLine(json); // {"Name":"Laptop","Price":1500.75}

var deserialized = JsonSerializer.Deserialize<Product>(json);
Console.WriteLine(deserialized?.Name); // Laptop
Enter fullscreen mode Exit fullscreen mode

Additionally, handling large collections has been improved, reducing processing time for data-intensive applications.


2.2. Goodbye to BinaryFormatter

With .NET 9, Microsoft has officially removed BinaryFormatter. This decision, driven by security concerns, encourages developers to adopt modern alternatives like System.Text.Json, XmlSerializer, or specific solutions like Protobuf.

What does this mean for you?

The removal of BinaryFormatter pushes developers toward modern serialization tools like System.Text.Json, but this shift highlights the importance of managing secrets such as API keys or certificates securely. Many developers face the risk of exposing sensitive data in their codebases. Tools like ByteHide Secrets streamline this process by securely storing and dynamically managing secrets, ensuring they remain protected and up-to-date, even as application needs evolve.


2.3. System.Linq Optimizations

LINQ, one of the most beloved tools in .NET, has received significant optimizations in this version. The new TryGetNonEnumeratedCount functionality allows you to get the size of a collection without fully enumerating it, saving time and resources in data-intensive scenarios.

Practical Example:

IEnumerable<int> numbers = Enumerable.Range(1, 1000);
if (numbers.TryGetNonEnumeratedCount(out int count))
{
    Console.WriteLine($"Number of elements: {count}");
}
Enter fullscreen mode Exit fullscreen mode

Moreover, common operations like Where and Select are now faster thanks to internal processing improvements.


2.4. Expanded Regex Support

In .NET 9, System.Text.RegularExpressions now includes support for precompiled regular expressions, enabling significantly better performance in scenarios where patterns are reused.

Practical Example:

var regex = new Regex(@"\d{4}-\d{2}-\d{2}", RegexOptions.Compiled);
Console.WriteLine(regex.IsMatch("2023-11-19")); // True
Enter fullscreen mode Exit fullscreen mode

This is especially useful for applications that process large volumes of text, such as validations and data analysis.


2.5. Logging with Source Generators

The logging system in .NET 9 has been optimized with the use of source generators, allowing log messages to be generated at compile time. This reduces runtime overhead and improves efficiency in applications that generate large amounts of logs.

[LoggerMessage(0, LogLevel.Information, "Application started at {StartTime}")]
public static partial void LogAppStart(this ILogger logger, DateTime StartTime);
Enter fullscreen mode Exit fullscreen mode

This not only improves performance but also minimizes errors in manually creating log messages.


2.6. KMAC Algorithm, ChaCha20-Poly1305, and HashData

.NET 9 extends its support for modern cryptographic algorithms, introducing KMAC and ChaCha20-Poly1305. These algorithms offer fast and secure encryption, especially useful for mobile applications, IoT, and other environments where performance is critical.

Practical Example:

using var chacha20 = new ChaCha20Poly1305(key);
byte[] ciphertext = chacha20.Encrypt(nonce, plaintext, associatedData);
Enter fullscreen mode Exit fullscreen mode

Moreover, the new HashData method simplifies the creation of secure hashes:

byte[] hash = SHA256.HashData(Encoding.UTF8.GetBytes("secure data"));
Console.WriteLine(Convert.ToBase64String(hash));
Enter fullscreen mode Exit fullscreen mode

Incorporating new cryptographic algorithms like KMAC and ChaCha20-Poly1305 enhances application security but requires reliable management of sensitive data. For this, ByteHide Storage offers an ideal solution, providing native integration with post-quantum cryptographic protocols such as Kyber and FrodoKEM. It ensures that sensitive data remains encrypted from end to end, even in cloud environments, addressing future-proofing concerns against emerging computational threats.

.NET 9 cryptography

2.7. Support for ref struct

The .NET 9 libraries now allow working with ref struct in more scenarios, opening up new possibilities for high-performance applications. This is particularly useful when handling sensitive data or large memory blocks.


2.8. Networking: HTTP/3 and More

.NET 9 enhances support for HTTP/3, enabling faster and more efficient connections. Additionally, sockets and System.Net.Http tools have been optimized to improve performance in network-dependent applications.

If you work with microservices or modern APIs, these improvements will help you take advantage of the latest network protocols.


2.9. Reflection Optimizations

Reflection, a critical tool for frameworks like ORMs or dependency injection systems, is now more efficient in .NET 9. Operations such as retrieving types or methods through System.Reflection execute faster, improving overall application performance.

Type type = typeof(MyClass);
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
Enter fullscreen mode Exit fullscreen mode

These optimizations are crucial for high-traffic applications that rely heavily on Reflection.


3. .NET SDK: Smarter Tools

The .NET 9 SDK introduces features that enhance version management and security audits:

3.1 Workload Sets

With .NET 9 simplifying workload management and improving compilation processes, ensuring the security of compiled binaries becomes essential. ByteHide Shield provides advanced features such as tamper detection and runtime integrity checks, safeguarding your software against unauthorized modifications while maintaining optimal performance and functionality.

3.2 Security Audits in NuGet

NuGet's improved security audits are a great step forward, but effectively managing and securing dependencies still requires a proactive approach. Tools like ByteHide Radar enhance this process by combining Software Composition Analysis (SCA) with Static Application Security Testing (SAST). This dual approach enables the identification of vulnerabilities not just in third-party packages, but also in your code, providing actionable recommendations to mitigate risks early in the development cycle.

.NET 9 Security

3.3 MSBuild Improvements

  • Parallel test execution.
  • New MSBuild script analyzers to detect configuration issues.
  • Shield now fully supports .NET 9, integrating enhanced protection mechanisms directly into the MSBuild process. It ensures that application code is secured during compilation, safeguarding against reverse engineering and tampering, while maintaining seamless compatibility with modern .NET workflows.

4. Artificial Intelligence: A Broader Focus

.NET 9 positions itself as a robust platform for AI with new tensor types and libraries for manipulating data and machine learning models.

4.1 TensorPrimitives and Tensor

These new types simplify complex mathematical operations for machine learning models.

Example:

Tensor<float> tensor = new Tensor<float>(new[] { 1.0f, 2.0f, 3.0f });
TensorPrimitives.Add(tensor.Span, 2.0f);
Enter fullscreen mode Exit fullscreen mode

4.2 ML.NET 4.0

  • New capabilities for tokenizers.
  • Improved ONNX model loading.
  • Integration with TorchSharp for advanced models like Llama.

5. .NET Aspire 9.0: Innovations for Distributed Applications

.NET ASPIRE 9

.NET Aspire 9.0 brings a series of significant updates that optimize the development, orchestration, and management of distributed applications. Designed to make the most of .NET 8 (LTS) and .NET 9 (STS), this version introduces improvements focused on developer experience, interactivity, and integrations. Here, we break down the most important innovations.


5.1. Improved Developer Experience

New Installation via SDK

Unlike previous versions, .NET Aspire 9 simplifies the environment setup by removing the need to install workloads. You can now install the SDK directly in the app host project.

Example of updated template installation:

dotnet new install Aspire.ProjectTemplates::9.0.0
Enter fullscreen mode Exit fullscreen mode

This makes the initial setup more agile and flexible for developers working on multiple Aspire projects.


5.2. Dashboard Improvements: Management and Interactivity

The .NET Aspire 9 dashboard introduces new features to facilitate the administration of distributed applications.

Resource Lifecycle Management

You can now stop, start, and restart individual resources directly from the dashboard without restarting the entire app host. This is useful for making quick changes to projects, containers, or executables.

Example: Reassign a debugger after restarting a project:

  • Debugging resources reattach automatically when restarted.

Mobile Compatibility

The dashboard is now responsive, allowing applications to be managed from mobile devices with an optimized user experience.

Sensitive Properties and Volumes

You can now mark properties as sensitive, automatically masking them in the interface. Additionally, the visualization of configured volumes and health checks has been improved.

# Command to filter logs with masked sensitive properties
dotnet-aspire dashboard --filter sensitive
Enter fullscreen mode Exit fullscreen mode

5.3. Optimized Telemetry

.NET 9 Optimization

Telemetry is more flexible and powerful in this version, with features such as:

  • Advanced Filters: You can now filter traces by specific attributes, like HTTP routes.
  • Integration with OpenTelemetry from the browser: Web applications can send structured logs, traces, and metrics to the dashboard.

Example: Configuring OpenTelemetry in a SPA:

import { trace } from '@opentelemetry/api';
trace.getTracer('aspire-tracer').startSpan('Request initiated');
Enter fullscreen mode Exit fullscreen mode

This ensures developers have a consolidated view of frontend and backend telemetry.


5.4. App Host and Orchestration

Wait for Dependencies

You can now define a resource to wait for another to be "ready" before starting. This is ideal for avoiding connection errors in containers.

var rabbit = builder.AddRabbitMQ("rabbit");
builder.AddProject<Projects.Api>("api")
       .WithReference(rabbit)
       .WaitFor(rabbit);
Enter fullscreen mode Exit fullscreen mode

Configurable Health Checks

Configurable health checks have been added to determine when a resource is operational. These checks can be based on HTTP states or specific configurations.

builder.AddContainer("catalog-api")
       .WithHttpHealthCheck("/health")
       .WithLifetime(ContainerLifetime.Persistent);
Enter fullscreen mode Exit fullscreen mode

This ensures dependent resources only start when they are fully functional.


5.5. Persistent Containers

You can now define persistent containers that are not deleted when the app host stops. This is useful for resources that need to remain operational regardless of the application's lifecycle.

Example: Create a persistent container for RabbitMQ:

var queue = builder.AddRabbitMQ("rabbit")
                   .WithLifetime(ContainerLifetime.Persistent);
Enter fullscreen mode Exit fullscreen mode

5.6. Improved Integrations

Redis Insight

Redis integration now includes support for Redis Insight, offering a graphical interface to visualize and manage data in real-time.

builder.AddRedis("redis")
       .WithRedisInsight();
Enter fullscreen mode Exit fullscreen mode

Azure Functions (Preview)

.NET Aspire 9 introduces preliminary support for Azure Functions, allowing serverless functions to be integrated directly into the host.

Example: Configure an HTTP function in Azure Functions:

builder.AddAzureFunctionsProject<Projects.MyFunctionApp>("functionapp")
       .WithExternalHttpEndpoints();
Enter fullscreen mode Exit fullscreen mode

5.7. Customization of Azure Container Apps

APIs have been added to customize Azure Container Apps without modifying infrastructure files (Bicep).

For example, you can now scale an application to zero replicas programmatically:

builder.AddAzurePostgresFlexibleServer("pgsql")
       .RunAsContainer()
       .PublishAsAzureContainerApp((module, containerApp) =>
       {
           containerApp.Template.Value!.Scale.Value!.MinReplicas = 0;
       });
Enter fullscreen mode Exit fullscreen mode

6. ASP.NET Core 9.0: Essential Improvements for Modern Web Applications

ASP.NET Core 9

ASP.NET Core 9.0 continues to strengthen its position as the ideal framework for building fast, efficient, and modern web applications. This version introduces significant optimizations in serving static files, new capabilities in Blazor and SignalR, and improvements in minimal APIs. Below, we explore these updates from a developer's perspective.


6.1. Static Asset Delivery Optimization

The new MapStaticAssets function revolutionizes how ASP.NET Core applications serve static files. Now, production best practices like compression, caching, and ETag usage can be implemented without complex manual configurations.

What Makes MapStaticAssets Different?

  • Advanced Compression: Support for gzip in development and gzip + Brotli in production.
  • Content-Based ETags: Ensures browsers only download files if the content has changed.
  • Reduced Size: Example with MudBlazor:
    • Original: 588.4 KB.
    • Compressed: 46.7 KB (92% reduction).
var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapStaticAssets();
app.MapRazorPages();

app.Run();
Enter fullscreen mode Exit fullscreen mode

When to Use It?

Replace UseStaticFiles in most cases, except when serving files from external locations, such as disks.


6.2. Blazor: More Integration and New Capabilities

Template for Blazor and .NET MAUI Hybrid Solutions

A new template simplifies creating native and web applications that share the same user interface. This approach fosters code reuse and supports multiple platforms like Android, iOS, Mac, Windows, and Web.

dotnet new maui-blazor-web
Enter fullscreen mode Exit fullscreen mode

Improved Server-Side Reconnection

  • Immediate reconnection when the browser returns to a sleeping tab.
  • Configurable backoff strategies to customize retry intervals.
Blazor.start({
  circuit: {
    reconnectionOptions: {
      retryIntervalMilliseconds: (previousAttempts) => previousAttempts * 1000,
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

6.3. SignalR: Enhanced Real-Time Communication

Support for Polymorphic Types in Hubs

SignalR now allows using base classes to enable polymorphic scenarios in Hub methods.

[JsonPolymorphic]
[JsonDerivedType(typeof(JsonPersonExtended))]
public class JsonPerson { public string Name { get; set; } }

public class MyHub : Hub
{
    public void HandlePerson(JsonPerson person) => Console.WriteLine(person.Name);
}
Enter fullscreen mode Exit fullscreen mode

Real-time communication frameworks like SignalR bring great interactivity but also introduce runtime vulnerabilities. Ensuring runtime security is critical, especially in distributed or IoT environments. With ByteHide Monitor, you can continuously protect your applications by dynamically detecting and neutralizing runtime threats, offering peace of mind in scenarios where secure environments cannot be guaranteed.

WebSocket Compression for Interactive Components

By default, SignalR enables compression for WebSocket, improving efficiency in real-time connections.


6.4. Minimal APIs: Simplification and Extensibility

New Methods in TypedResults

ASP.NET Core 9.0 introduces new methods in TypedResults, like InternalServerError, which facilitates error handling in minimal APIs.

app.MapGet("/", () => TypedResults.InternalServerError("Internal error"));
Enter fullscreen mode Exit fullscreen mode

OpenAPI Compatibility

You can now generate OpenAPI documentation directly from your controllers or minimal APIs, with support for Native AOT.

builder.Services.AddOpenApi();
app.MapOpenApi();
Enter fullscreen mode Exit fullscreen mode

6.5. Additional Improvements

  • Integration with Bootstrap 5.3.3 and jQuery 3.7.1.
  • Updated support for authentication and authorization with OpenID Connect.
  • Advanced metrics in Kestrel: Includes detailed reasons for connection closures.

7. C# 13: The 11 Most Notable Language Updates

Based on the insightful session led by Mads Torgersen and Dustin Campbell at the .NET Conf 2024, we’ve compiled a concise summary of the most exciting new features and enhancements introduced in C# 13. This overview highlights the key advancements designed to improve developer productivity, streamline coding workflows, and expand the language's capabilities for modern applications. Stay tuned to explore what makes C# 13 a game-changer for the .NET ecosystem.

C# 13 NEWS

With the arrival of C# 13, developers have access to new tools and features designed to improve productivity, reduce repetitive code, and make the most out of .NET 9. Here is a complete breakdown of the 11 updates introduced in this version.


7.1. More Flexible String Interpolation

One of the most anticipated updates is the ability to nest interpolated expressions directly within a string. This eliminates the need for additional concatenations.

int x = 5, y = 10;
Console.WriteLine($"The sum of {x} and {y} is {x + y}");
Enter fullscreen mode Exit fullscreen mode

Now you can build more complex strings without worrying about errors or lack of clarity.


7.2. Named Parameters in Attributes

C# 13 allows passing arguments to attributes using parameter names, which improves readability and reduces errors when working with metadata.

[ExampleAttribute(Required = true, Message = "This field is required")]
public string Field { get; set; }
Enter fullscreen mode Exit fullscreen mode

This syntax is especially useful when working with attributes that have multiple optional parameters.


7.3. Improved ref fields in Structs

The optimized handling of ref struct in .NET 9 allows developers to enhance performance in memory-intensive applications. However, securing these performance-critical components is equally important. Solutions like ByteHide Shield protect your intellectual property by combining robust obfuscation techniques, control flow protection, and anti-debugging measures, making it nearly impossible for attackers to reverse-engineer or tamper with your software.

ref struct MyStruct
{
    public ref int MyField;
    public MyStruct(ref int value)
    {
        MyField = ref value;
    }
}
Enter fullscreen mode Exit fullscreen mode

This greatly benefits high-performance applications that manipulate sensitive or complex data.


7.4. List Initialization in Collection Expressions

C# 13 introduces a cleaner syntax for initializing lists and collections, eliminating the need for verbose initializers.

var numbers = [1, 2, 3, 4, 5];
Enter fullscreen mode Exit fullscreen mode

This new syntax makes the code more intuitive, especially when working with large data structures.


7.5. Safe Access to Nullable Properties

The safe access operator now extends to object initializers, improving safety and readability in complex structures.

var person = new Person
{
    Name = anotherObject?.Property ?? "Unknown"
};
Enter fullscreen mode Exit fullscreen mode

This reduces the risk of runtime exceptions when working with potentially null data.


7.6. Improvements in readonly struct

It is now possible to declare extension methods on readonly struct without losing the benefits of immutability.

public readonly struct Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y) => (X, Y) = (x, y);

    public int CalculateDistance() => Math.Abs(X - Y);
}
Enter fullscreen mode Exit fullscreen mode

This improvement simplifies working with immutable structs, making the code clearer and more efficient.


7.7. Improved Constant Handling

C# 13 allows defining constants that were previously not possible, such as DateTime values.

public const DateTime StartDate = new DateTime(2024, 1, 1);
Enter fullscreen mode Exit fullscreen mode

This makes it easier to use predefined constants in configurations and static data.


7.8. Changes in Pattern Matching

Improvements have been introduced that expand the capabilities of pattern matching, including support for more complex logical patterns.

if (obj is int i and > 0)
{
    Console.WriteLine($"Positive number: {i}");
}
Enter fullscreen mode Exit fullscreen mode

These updates make the code more expressive and less error-prone.


7.9. Improved switch with Type Expressions

You can now combine type expressions and patterns in more compact switch statements.

string GetMessage(object obj) => obj switch
{
    int i => $"It's a number: {i}",
    string s => $"It's a string: {s}",
    _ => "Unknown type"
};
Enter fullscreen mode Exit fullscreen mode

This approach simplifies logic and improves code clarity.


7.10. New Capabilities in String Interpolation

It is now possible to use interpolated expressions in more contexts, such as property initializers.

var message = new { Text = $"Hello, {user.Name}" };
Enter fullscreen mode Exit fullscreen mode

This makes handling dynamic strings even more natural.


7.11. Enhanced Generic Constraints

Finally, C# 13 introduces new capabilities in generic constraints, allowing for more flexible and robust method definitions.

public static void Process<T>(T element) where T : notnull
{
    Console.WriteLine(element);
}
Enter fullscreen mode Exit fullscreen mode

These improvements are essential for libraries that handle multiple data types safely.

8. What's New in F# 9

F# 9 adds features focused on security and productivity:

  1. Support for nullable reference types.
  2. .Is* properties for discriminated unions.
  3. Partial active patterns can now return bool.
  4. Preference for extension methods over intrinsic properties.
  5. Empty body expressions for computation expression builders.
  6. New randomization functions for collections.
  7. Improved compatibility with C# collections.

9. What's New in .NET MAUI for .NET 9: More Power and Flexibility for Cross-Platform Apps

.NET MAUI for .NET 9 news

Version 9 of .NET MAUI (Multi-platform App UI) focuses on improving product quality and expanding its capabilities. With new controls, performance improvements, and developer tools, this update sets a higher standard for cross-platform applications on Android, iOS, Mac Catalyst, and Windows.


9.1. Minimum Deployment Requirements

.NET MAUI 9 updates its deployment targets:

  • iOS: Minimum required 12.2.
  • Mac Catalyst: Minimum required 15.0 (macOS 12.0).
  • Android and Windows: No changes from previous versions.

9.2. New Controls

HybridWebView

The HybridWebView control allows hosting HTML, CSS, and JavaScript content directly in a native .NET MAUI application. It also facilitates two-way communication between JavaScript code and C#.

Main Use:

  • Ideal for integrating existing web applications like React or Angular within a MAUI app.
  • Enables execution of local web content on the device.
<HybridWebView Source="index.html"
               HostPage="wwwroot/index.html" />

Enter fullscreen mode Exit fullscreen mode

TitleBar for Windows

You can now customize the title bar of your Windows application using the TitleBar control.

WPF in .NET 9

Example in XAML:

<Window.TitleBar>
    <TitleBar Title="My Application"
              Icon="icon.png"
              HeightRequest="46">
        <TitleBar.Content>
            <SearchBar Placeholder="Search here"
                       HorizontalOptions="Fill"
                       VerticalOptions="Center" />
        </TitleBar.Content>
    </TitleBar>
</Window.TitleBar>

Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Fully customizable: Add main content, start content, and end content.
  • Supports dark and light themes.
  • Upcoming support: Mac Catalyst in a future release.

News in .NET 9


9.3. Improvements to Existing Controls

BlazorWebView

  • On iOS and Mac Catalyst, BlazorWebView content is now hosted by default on localhost, improving stability.
  • Introduction of fire-and-forget option for asynchronous disposal, reducing risks of deadlocks.

CollectionView and CarouselView

  • New optional handlers have been added to improve performance and stability on iOS and Mac Catalyst.
builder.ConfigureMauiHandlers(handlers =>
{
    handlers.AddHandler<CollectionView, CollectionViewHandler2>();
    handlers.AddHandler<CarouselView, CarouselViewHandler2>();
});

Enter fullscreen mode Exit fullscreen mode

Soft Keyboard

Expanded support for specific input types such as:

  • Password, Date, and Time in controls like Entry and Editor.
<Entry Keyboard="Date" />

Enter fullscreen mode Exit fullscreen mode

9.4. Compiled Bindings in Code and XAML

Compiled Bindings in Code

.NET MAUI 9 introduces compiled bindings that eliminate the need to use strings for property paths, reducing errors and improving performance.

MyLabel.SetBinding(Label.TextProperty, static (Entry entry) => entry.Text);

Enter fullscreen mode Exit fullscreen mode

Advantages:

  • Compile-time validation of bindings.
  • Better debugging experience.
  • Full support in NativeAOT.

9.5. Compilation with Native AOT and Full Trimming

Native AOT

.NET MAUI 9 enables Ahead of Time (AOT) compilation for iOS and Mac Catalyst. This results in applications that are:

  • 2.5x smaller.
  • 2x faster at startup.

Full Trimming

Removes unnecessary code from applications to reduce their size. Configurable in the project file:

<PropertyGroup>
    <TrimMode>Full</TrimMode>
</PropertyGroup>

Enter fullscreen mode Exit fullscreen mode

Limitations: Some features, like HybridWebView, are not compatible with full trimming.


9.6. Project Templates and Practical Examples

New templates include:

  1. Todo List Apps: Based on SQLite with visualization thanks to the Syncfusion toolkit.
  2. Blazor Hybrid Templates: Combine native and web applications using Blazor.
dotnet new maui --sample-content -n MyProject
dotnet new maui-blazor-web -n MyBlazorProject

Enter fullscreen mode Exit fullscreen mode

9.7. Native API and Multi-Window Support

Native API

.NET MAUI now includes complete APIs for native integration scenarios, simplifying the conversion of .NET MAUI views to their native equivalents.

var nativeView = mauiView.ToPlatform(mauiApp.Services);

Enter fullscreen mode Exit fullscreen mode

Multi-Window Support

Ability to activate specific windows on Mac Catalyst and Windows:

Application.Current?.ActivateWindow(windowToActivate);

Enter fullscreen mode Exit fullscreen mode

9.8. Compatibility and Deprecated APIs

Key Deprecations:

  • The Frame control has been replaced by Border.
  • The MainPage property is now set in Window.Page for greater flexibility.

Extended Compatibility:

  • Full support for iOS 18 and Mac Catalyst 15 with Xcode 16.
  • Android API level 35.

10. WPF in .NET 9: Revamping Desktop UI Development

Windows Presentation Foundation (WPF) continues to evolve to offer modern and flexible tools for desktop application development. In .NET 9, WPF focuses on enhancing visual capabilities and introducing new features, such as support for Fluent themes and Windows accent colors. Here, we break down all the new updates.


10.1. Fluent Theme: Modern Style for Windows 11

The new Fluent theme introduces a more modern and consistent visual design aligned with Windows 11. This theme includes support for light and dark modes, as well as integration with the system accent color.

News in .NET 9

How to Apply It?

You can use the Fluent theme in two ways:

  1. Configuring the ThemeMode at the application or window level.
  2. Referencing the Fluent theme resource dictionary in the XAML file:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
Enter fullscreen mode Exit fullscreen mode

This integration ensures that WPF applications maintain a current design that meets user expectations.


10.2. ThemeMode Property for Dynamic Style Configuration

The new ThemeMode property makes it easier to configure the Fluent theme directly in the application or specific windows. You can define whether the app respects the system mode, stays fixed in light or dark mode, or uses the classic Aero2 theme.

News in .NET 9

Example: Configure Dark Mode at the Window Level:

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        Title="Main Window"
        ThemeMode="Dark">
</Window>
Enter fullscreen mode Exit fullscreen mode

This flexible approach simplifies app customization and ensures a consistent experience across devices.


10.3. Custom Accent Colors

WPF now allows leveraging the user's configured accent color in Windows, adding a personal touch to interfaces. It also offers light and dark versions of this color, ready to be used dynamically in your applications.

How to Use the Accent Color?

<TextBlock Text="Welcome"
           Foreground="{DynamicResource {x:Static SystemColors.AccentColorBrushKey}}" />
Enter fullscreen mode Exit fullscreen mode

With this configuration, any change in the system accent color will automatically reflect in the application without needing a restart.


10.4. Hyphen-Based Ligature Support

In response to community requests, WPF in .NET 9 adds support for hyphen-based ligatures within text controls like TextBlock. This significantly improves the aesthetics of typography in applications that rely on advanced fonts.

In .NET 8:

News in .NET 9

In .NET 9 🔥

News in .NET 9


10.5. Removal of BinaryFormatter

As part of an ongoing effort to improve security, WPF completely removes BinaryFormatter, which has been deemed unsafe due to deserialization vulnerabilities. Now, any attempt to use it will throw a PlatformNotSupportedException.

What to Do If You Still Use BinaryFormatter?

You should migrate to modern alternatives, such as System.Text.Json or XmlSerializer, to handle data securely.

11. Windows Forms in .NET 9: New Capabilities for Modern Desktop Applications

Windows Forms remains a solid and reliable solution for desktop application development on Windows. With .NET 9, the platform introduces key improvements in functionality, compatibility, and design, integrating modern features that make desktop applications more efficient and visually appealing. Here are the most important updates.


11.1. Asynchronous Forms (Experimental)

Modern development requires compatibility with asynchronous communication models. In .NET 9, Windows Forms adds experimental support for asynchronous forms, including methods like Form.ShowAsync, Form.ShowDialogAsync, and Control.InvokeAsync. This allows handling operations that require synchronization with the UI thread, such as WebView2 or libraries like Semantic Kernel.

Configuration to Use This Feature:

To enable these experimental APIs, add the following configuration to the project file:

<PropertyGroup>
    <NoWarn>$(NoWarn);WFO5002</NoWarn>
</PropertyGroup>
Enter fullscreen mode Exit fullscreen mode

This advancement is essential for applications that integrate multiple frameworks or require smooth communication between asynchronous components.


11.2. Goodbye to BinaryFormatter

Following best security practices, Windows Forms has removed the use of BinaryFormatter, a class vulnerable to deserialization attacks. Now, attempting to use this functionality will throw a PlatformNotSupportedException.

Windows Forms has internally replaced this dependency with a more secure subset for specific scenarios, such as clipboard operations and the form designer.

What Does This Mean?

If you still rely on BinaryFormatter, it is crucial to migrate to modern alternatives like System.Text.Json or XmlSerializer.


11.3. Experimental Support for Dark Mode

.NET 9 introduces preliminary support for dark mode in Windows Forms, with plans for completion in .NET 10. You can now set the system color mode with a simple line of code:

Application.SetColorMode(SystemColorMode.Dark);
Enter fullscreen mode Exit fullscreen mode

Dark mode is ideal for applications that need to follow system preferences or provide a more comfortable experience in low-light environments.

Available Modes:

  • SystemColorMode.Classic: Light mode, as in previous versions.
  • SystemColorMode.System: Follows Windows settings.
  • SystemColorMode.Dark: Activates dark mode directly.

11.4. Improvements in FolderBrowserDialog

One of the most requested improvements is the ability to select multiple folders in FolderBrowserDialog. This is now possible by setting the Multiselect property to true.

var dialog = new FolderBrowserDialog
{
    Multiselect = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
    foreach (var path in dialog.SelectedPaths)
    {
        Console.WriteLine($"Selected folder: {path}");
    }
}
Enter fullscreen mode Exit fullscreen mode

This simplifies tasks such as bulk operations across multiple directories.


11.5. New Capabilities in System.Drawing

The System.Drawing library has received several improvements, including:

Image Effects with GDI+

You can now apply advanced visual effects, such as blurs, contrast adjustments, and tints, directly to bitmaps.

var bitmap = new Bitmap("image.jpg");
var effect = new System.Drawing.Imaging.Effects.BlurEffect();
bitmap.ApplyEffect(effect, Rectangle.Empty);
Enter fullscreen mode Exit fullscreen mode

These capabilities allow adding high-quality graphics to your applications without the need for external tools.

Span Compatibility

Many methods that previously only accepted arrays now support ReadOnlySpan, optimizing memory handling and improving performance.

Graphics.DrawLines(Pens.Black, new ReadOnlySpan<Point>(points));
Enter fullscreen mode Exit fullscreen mode

11.6. Improvements in ToolStrip

The ToolStrip control now includes new properties and events that enhance its functionality:

  • AllowClickThrough: Allows interaction with the control even when the window is not focused.
  • SelectedChanged: Event that detects when a menu item is highlighted, replacing the functionality of the deprecated MenuItem.Select.
var toolStripItem = new ToolStripMenuItem("File");
toolStripItem.SelectedChanged += (sender, args) => Console.WriteLine("Item selected");
Enter fullscreen mode Exit fullscreen mode

These improvements allow building more dynamic and functional menus.

As we move forward into a new era of software development, .NET 9 emerges as a powerful platform that empowers developers to build more secure, efficient, and innovative applications. With advancements spanning across various areas, from modernizing desktop applications with Windows Forms and WPF to enhancing cross-platform capabilities with .NET MAUI, .NET 9 caters to a wide range of development needs.

The inclusion of updates in C#, F#, and the integration of new performance and security features ensures that .NET developers are equipped with state-of-the-art tools to stay ahead in an ever-evolving tech landscape. Whether you're developing for the web, mobile, or desktop, .NET 9 has something valuable to offer.

Take the opportunity to explore these new features, experiment with the latest improvements, and continue building the future of software with .NET 9. The journey of innovation has just begun, and the tools are now in your hands.

Top comments (1)

Collapse
 
jangelodev profile image
João Angelo

Hi ByteHide,
Top 5, very nice and helpful !
Thanks for sharing.