【Re-evaluating?】.NET 6 Preview 1 Hands-on! Experience the New Version Updates!

2021年2月19日 62点热度 1人点赞 4条评论
内容目录

目录

Recently, .NET 6 Preview 1 has been released, and the unification of .NET is at the core of this version. You may read the original blog post:

https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-1/

Download link for .NET 6.0 SDK and Runtime:

https://dotnet.microsoft.com/download/dotnet/6.0

Below, I will introduce the current updates in .NET 6 Preview 1 and try out some interesting new features.

This article is not a translation; it is handcrafted.

Cross-Platform UI Applications

.NET 6 has unified multi-platform (Android, iOS, etc.) UI applications, providing a consistent experience across various platforms and devices, enabling more shared code between mobile applications and PC desktop programs. The multi-platform unified toolkit is based on the integration and extension of Xamarin.Forms, allowing for the development of desktop applications for Windows, macOS, Android, and iOS.

Currently, Visual Studio supports Windows and macOS. On machines with .NET 6 SDK installed, desktop applications can run on Windows and macOS. To support Android and iOS, two additional packages must be downloaded. This is because Windows and macOS can run applications by installing the .NET 6 Runtime and executing .dll files (IL intermediate code), while Android and iOS publish and run native code.

# Windows Download
Microsoft.NET.Workload.Android.11.0.200.85.msi
Microsoft.NET.Workload.iOS.14.3.100-ci.main.1079.msi

# MacOS Download
Microsoft.NET.Workload.Android-11.0.200-ci.master.85.pkg
Microsoft.iOS.Bundle.14.3.100-ci.main.1079.pkg

Readers can find download links at https://github.com/dotnet/net6-mobile-samples but note that downloads may not work without a proxy.

Creating Xamarin Project

The .NET 6 runtime has special tags for Android and iOS. To support mobile applications, you need to specify the name. For Android, in the .csproj file:

    <TargetFramework>net6.0-android</TargetFramework>

Here is a .csproj template for a Xamarin.Forms application:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net6.0-android;net6.0-ios</TargetFrameworks>
    <RuntimeIdentifier>ios-x64</RuntimeIdentifier>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Xamarin.Forms" Version="4.8.0.1364" GeneratePathProperty="true" />
  </ItemGroup>
</Project>

Of course, to publish or debug the application, SDKs or emulators are required. For Android, you need the Android SDK and Android SDK Platform 30. During publishing, you also need to specify:

dotnet build HelloForms -t:Run -f net6.0-android
dotnet build HelloForms -t:Run -f net6.0-ios

In the official sample project, nuget packages need to access pkgs.dev.azure.com, so they cannot be accessed without a proxy. Therefore, this sample project may not be feasible; take a look at it for enjoyment.

Currently, .NET 6 targeting includes:

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

Blazor Desktop Applications

I assume the happiest person upon seeing this update is James Yeung, the lead author of Ant Design of Blazor project.

ant-design-blazor

james_mvp

In .NET 6, Blazor can be integrated into UI applications, combining Web and native UI, which can be embedded and run in desktops. This Blazor hybrid development approach is known as Blazor Hybrid Apps.

.NET Core 3.0 supported Blazor Server, and 3.1 supported Blazor WebAssembly. Blazor WebAssembly uses the Mono runtime, which many .NET developers have likely experienced with Blazor development. Currently, WebAssembly is still quite large (.NET Core 3.x) and has issues like performance, but subsequent .NET versions have optimized it heavily.

In VS2019 Preview4, the template name changed to Blazor WebAssembly App, which is actually WebAssembly with the 'App' suffix, but it does not mean it is a UI application; it is still web-based.

BlazorWebAssemblyApp

Returning to the main point, the blog on .NET 6 mentions that Blazor can work with MAUI, but it does not provide a demo or implementation details, possibly still under development. Why could I not create it directly after downloading VS2019 Preview4? Am I being played? How do I experience Blazor development for desktop applications?

Recently, someone created this issue: https://github.com/Webreaper/Damselfly/issues/108

However, Blazor can indeed be combined with mobile applications. There is a project called Mobile Blazor Bindings that integrates Blazor into Xamarin, and this project has supported it since .NET Core 3.x.

Project address: https://github.com/dotnet/MobileBlazorBindings

Sample code:

<StackLayout>
    <Label FontSize="30">You pressed @count times </Label>
    <Button Text="+1" OnClick="@HandleClick" />
</StackLayout>

@code {
    int count;

    void HandleClick()
    {
        count++;
    }
}

mobileblazor

Such projects utilize the Microsoft.MobileBlazorBindings.Templates library, which encapsulates numerous Razor components.

We can create this type of project using the dotnet command. The corresponding templates are as follows:

Template Name                                   Short Name            Language    Tags
----------------------------------------------  --------------------  ----------  ------------------------
Experimental Mobile Blazor Bindings App         mobileblazorbindings  [C#]        Blazor/Xamarin.Forms
Experimental Mobile Blazor Bindings Hybrid App  blazorhybrid          [C#]        Blazor/Xamarin.Forms/Web

The mobileblazorbindings is not interesting, so don't try it.

We can use the command to create a template project:

 dotnet new blazorhybrid
Directory Structure:
H:.
├─HBlazor
│  ├─WebUI
│  │  ├─Pages
│  │  └─Shared
│  └─wwwroot
├─HBlazor.Android
│  ├─Assets
│  ├─Properties
│  ├─Resources
│  └─wwwroot
├─HBlazor.iOS
│  ├─Assets.xcassets
│  ├─Properties
│  └─Resources
│      └─wwwroot
├─HBlazor.macOS
│  ├─Assets.xcassets
│  └─Resources
│      └─wwwroot
└─HBlazor.Windows
    └─wwwroot

However, the official sample project has bugs and throws unexpected exceptions, so everyone should just try it for a bit.

blazorhybrid

The principle is that Microsoft.MobileBlazorBindings encapsulates a series of Razor components, and I create Razor files, referencing these components to build interfaces and implement dynamic operations.

Test code (Main.razor):

<ContentView>
    <StackLayout>
        <StackLayout Margin="new Thickness(20)" Orientation="StackOrientation.Horizontal">
            <Label Text="痴者工良" />
            
            <Image Source="@(new FileImageSource { File = "H:/文章/.NET6/mobileblazorbindings/HBlazor/Bugs.jpg" })" />
            <Label Text="@($ "Bug - {CounterState.CurrentCount}")" FontSize="40" HorizontalOptions="LayoutOptions.StartAndExpand" />
            <Button Text="解决 Bug" OnClick="@CounterState.IncrementCount" VerticalOptions="LayoutOptions.Center" Padding="10" />
        </StackLayout>

        <BlazorWebView VerticalOptions="LayoutOptions.FillAndExpand">
            <HBlazor.WebUI.App />
        </BlazorWebView>

    </StackLayout>
</ContentView>

Note: Currently, HTML tags like <br /> are not supported; Razor syntax can be used, but HTML cannot be directly used. This may indicate that Razor is converted to XAML, which means only the predefined components can be used. How to incorporate CSS is also an issue. This also indicates that JavaScript is not supported!

As for Blazor desktop apps mentioned in the .NET 6 blog, it appears as if the web version is embedded, but since it is not available for testing, we will skip it.

blazor-macos-768x508

Reviewing the cross-platform UI applications, Xamarin and Blazor are mainly mentioned. A new cross-platform app UI framework called MAUI is expected to appear in .NET 6. .NET MAUI is an evolution of Xamarin.Forms that surfaced in 2020. The purpose of this library is to unify the Xamarin SDK with .NET and also allow code sharing with other projects, such as Blazor.

Currently, there are two ways to try MAUI:

The latter has already been mentioned, and readers interested in MVU can try testing it themselves.

Not done yet! Although information regarding Blazor - desktop applications in .NET 6 is quite limited, we can take a look at other frameworks, such as LiveSharp.

System.CommandLine

In the past, when we wanted to execute commands, such as viewing the process list and resource consumption on Linux, we would use top -b -n 1. In C# code, it would look like this:

var psi = new ProcessStartInfo("top", "-b -n 1") { RedirectStandardOutput = true };
var proc = Process.Start(psi);

Of course, there are other methods, but they seem a bit convoluted and hard to understand. In the previous example, the top command is treated as a process with parameters for starting, but this only suits one-time programs. For instance, top is analogous to the task manager in Windows, where -n 1 means it prints output once and terminates. If you directly call top, it will continue to run dynamically and will not terminate on its own, which may lead to issues. This method isn't suitable for interactive programs or command lines, as continuously running invoked programs can create problems; commands like cat /etc/os-release, ls -lah output once easily processed without issues.

There is also the situation of writing command line programs. For example, I wrote a dotnet tool named csys to view host information, where users can input commands along with parameters to determine the desired functionality:

public static class Command
{
    public const string Info = "info";
}

Console.WriteLine("Please enter a command"); // Or using Main(string[] args) to get args
string command = "";
command = Console.ReadLine();
// netinfo
if (command == Command.NETINFO)
    NETINFO();

This method is too clumsy, and there isn't a better way to handle it.

In order to cross platforms more easily, .NET 6 introduced the System.CommandLine package, which provides a more convenient way to execute commands and build command-line programs.

This library offers extensive functionality, and interested readers can refer to: https://github.com/dotnet/command-line-api

Using this library, we can easily create command-line applications similar to wget or curl.

For instance, we create a myapp command-line program and allow users to execute it like this:

$> myapp [parse] --int-option not-an-int --file-option file.txt

To handle these parameters, we tend to utilize string[] and if, which seems less flexible. System.CommandLine has an Option<T> that assists programmers in managing these parameters more effectively:

// Create a root command with some options
var rootCommand = new RootCommand
{
    new Option<int>(
        "--int-option",
        getDefaultValue: () => 42,
        description: "An option whose argument is parsed as an int"),
    new Option<bool>(
        "--bool-option",
        "An option whose argument is parsed as a bool"),
    new Option<FileInfo>(
        "--file-option",
        "An option whose argument is parsed as a FileInfo")
};

For instance, new Option<int> indicates if --int-option is recognized as a parameter, then the value following it is an integer type, such as:

--int-option 123

getDefaultValue:() => 42 sets a default value that will be used if the user does not provide it when launching the command.

If this parameter is not specified, this Option<T> will use the default value, for example:

# Without any parameters
$> myapp

The C# code that handles these parameters is as follows:

   // Note that the parameters of the handler method are matched according to the names of the options
   rootCommand.Handler = CommandHandler.Create<int, bool, FileInfo>((intOption, boolOption, fileOption) =>
    {
        Console.WriteLine($"The value for --int-option is: {intOption}");
        Console.WriteLine($"The value for --bool-option is: {boolOption}");
        Console.WriteLine($"The value for --file-option is: {fileOption?.FullName ?? "null"}");
    });

Output result:

The value for --int-option is: 42
The value for --bool-option is: False
The value for --file-option is: null

Example code or program can be referred to: https://github.com/dotnet/command-line-api/blob/main/docs/Your-first-app-with-System-CommandLine.md

Other Updates

Other updates are mainly textual, and the author has summarized some of the more eye-catching information:

  • Arm64
    .NET5 made significant performance improvements for the Arm64 version, and .NET6 continues to enhance performance;
    Plans to support running WPF on Windows Arm64 machines;
    Support for Apple Silicon (Arm64) chips (both natively and in emulation);

  • Containers (Docker)
    Optimized performance of .NET applications in containers;
    Optimized the size of official images (using PGO technology);
    Various ways to improve startup and throughput performance;
    Updated the version of the base image;

  • System.Numerics
    A set of new mathematical APIs to improve performance in mathematical operations and enhance performance based on hardware;

  • Improve single-file size

    The packaging format of the released binaries can improve size; however, the previously mentioned extreme AOT optimizations have not yet emerged;

  • Crossgen2
    Roslyn is an API set in C# for syntax analysis and compiling C# code, which can compile C# code into .dll; whereas crossgen2 can compile to native code rather than .dll, crossgen2 is written in C# and can self-boot; crossgen2 is only applicable to CoreCLR;

ASP.NET Core

The ASP.NET Core roadmap is independent of .NET; more information can be found at: https://themesof.net/, which is written in Blazor. For some reason, the website content does not load, which is quite unfriendly. You can also find some roadmap plans here: https://github.com/dotnet/aspnetcore/issues/27883

The main planned content for .NET6 includes:

  • Hot Reload
    During development, there is no need to recompile to update the UI and code of a running application. This makes it easier to write Blazor, MVC, and API;

  • Minimal APIs
    The documentation states: simplify building API endpoints with less code and ceremony. However, after viewing the issue, it appears that this merely reduces unnecessary .dll when learning or writing simple APIs, thus minimizing size;

  • Single-file publishing
    Build small, standalone, high-performance applications and services;

  • WebAssembly Ahead-of-Time (AoT) compilation
    When publishing, the .NET code in Blazor WebAssembly applications is compiled directly into WebAssembly, significantly improving runtime performance. This can reduce some .dll files;

  • SPA Integration
    Unsure what this is, the documentation mentions seamless cooperation with the latest modern front-end JavaScript frameworks;

  • Blazor hybrid desktop apps
    As mentioned earlier, UI applications can be developed using Blazor together with MAUI;

  • HTTP/3
    Support for HTTP/3; enhance support capabilities;

Now let's discuss the current updates of .NET 6 Preview 1.

  • IAsyncDisposable Support in MVC

    Now the IAsyncDisposable interface can be implemented on controllers, page models, and view components to asynchronously dispose of resources.

  • DynamicComponent

    DynamicComponent is a new built-in Blazor component for dynamically rendering components specified by type.

<DynamicComponent Type="@someType" />

Parameters can be passed to the rendered component using a dictionary:

<DynamicComponent Type="@someType" Parameters="@myDictionaryOfParameters" />

@code {
    Type someType = ...
    IDictionary<string, object> myDictionaryOfParameters = ...
}
  • ElementReference

    ElementReference is an object for passing HTML element references. In JS, we can use document.getElementById('someId') to locate elements, but in Blazor, many components are dynamically composed, making it difficult to ensure IDs are unique or accurately located. To address this, Blazor uses @ref element tags and the ElementReference struct. Interested readers can check Passing HTML element references. Now ElementReference provides a more convenient way to handle input components like InputCheckbox, InputDate, InputFile, InputNumber, InputSelect, InputText, and InputTextArea, such as setting the UI focus on these input components.

  • Nullable Reference Type Annotations
    This is an excellent specification constraint. Now all parts of ASP.NET Core have these annotations added, which can significantly enhance the compile safety of projects. Projects that choose to use nullable annotations may see new compile-time warnings from the ASP.NET Core API.

Additionally, there have also been some updates to EFCore, but there are no significant impacts, so I won't mention them here.

痴者工良

高级程序员劝退师

文章评论