.NET 10 Preview 6 run file 优化
Intro
.NET 10 在之前的 Preview 4 版本中开始引入 dotnet run file 支持,还不清楚的朋友可以先移步 你好 dotnet run file, 再见 csproj ,在 Preview 5/6 中又有一些优化来优化和改进使用体验,我们一起来看看有哪些改进
Enhanced run experience
在之前的版本中我们需要使用 dotnet run hello.cs
来执行单个文件,现在可以直接使用 dotnet hello.cs
了,对于 shebang 之前需要使用 #!/usr/bin/dotnet run
来指定使用 dotnet run
来执行,在 .NET 10 Preview 6 中我们可以去掉 run
直接使用 #!/usr/bin/dotnet
即可,这样使用起来更加的方便,可以像 node hello.js 一样使用了
例如:
#!/usr/bin/dotnet
Console.WriteLine("Hello .NET");
build/publish support
现在我们除了直接运行外,我们还可以使用 dotnet restore/build/publish
如果我们只想验证是否能够编译通过,那么我们就可以使用 dotnet build hello.cs
来验证了
除了这两个之外,值得一提的是支持 dotnet publish,可以将单个文件直接发布成可执行的应用程序,并且默认会启用 AOT 的发布
AOT 除 dotnet SDK 外需安装额外的编译工具链,详见:https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8&WT.mc_id=DT-MVP-5004222#prerequisites
publish 之后的大小只有 1.2 MB:
我们也可以使用在文件中指定 #property PublishAot=false
来不 publish aot,也可以 publish 的时候指定比如 :
dotnet publish hello.cs -p PublishAot=false
从 publish 的结果可以看出,没有 aot publish 的时候会有 runtimeconfig.json
以及 deps.json
文件输出,aot publish 的时候是没有的
Project reference support
现在可以引用某一个 project 了,可以指定到项目文件所在目录也可以指定到具体的项目文件,如下所示:
#:project ../Net10Samples
Net10Samples.JsonSamples.JsonIgnoreWhenReadWriteSample();
More
除了上面的更新之外,还有一些更新,比如 SDK 也可以支持 version,这样也可以指定使用指定版本的 Aspire Sdk 了,比如: \#:sdk Aspire.AppHost.Sdk@9.3.1
#:property
指令现在需要 =
符号来分隔属性名称和值,以更好地与项目文件中的语法对齐,例如 #:property LangVersion=preview
另外现在支持执行没有扩展名的文件了,之前需要执行 .cs
文件,现在没有扩展名有 shebang 也可以执行
# 1. Create a single-file C# app with a shebang
cat << 'EOF' > hello.cs
#!/usr/bin/env dotnet
Console.WriteLine("Hello!");
EOF
# 2. Copy it (extensionless) into ~/utils/hello (~/utils is on my PATH)
mkdir -p ~/utils
cp hello.cs ~/utils/hello
# 3. Mark it executable
chmod +x ~/utils/hello
# 4. Run it directly from anywhere
cd ~
hello
最后我们可以在运行时获取到当前的 run file 的信息,示例如下:
#:property LangVersion=preview
Console.WriteLine("From [CallerFilePath] attribute:");
Console.WriteLine($" - Entry-point path: {Path.EntryPointFilePath()}");
Console.WriteLine($" - Entry-point directory: {Path.EntryPointFileDirectoryPath()}");
Console.WriteLine("From AppContext data:");
Console.WriteLine($" - Entry-point path: {AppContext.EntryPointFilePath()}");
Console.WriteLine($" - Entry-point directory: {AppContext.EntryPointFileDirectoryPath()}");
staticclassPathEntryPointExtensions
{
extension(Path)
{
public static string EntryPointFilePath() => EntryPointImpl();
public static string EntryPointFileDirectoryPath() => Path.GetDirectoryName(EntryPointImpl()) ?? "";
private static string EntryPointImpl([System.Runtime.CompilerServices.CallerFilePath] string filePath = "") => filePath;
}
}
staticclassAppContextExtensions
{
extension(AppContext)
{
publicstaticstring? EntryPointFilePath() => AppContext.GetData("EntryPointFilePath") asstring;
publicstaticstring? EntryPointFileDirectoryPath() => AppContext.GetData("EntryPointFileDirectoryPath") asstring;
}
}
References
o https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview6/sdk.md#file-based-apps o https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/sdk?WT.mc_id=DT-MVP-5004222 o https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8&WT.mc_id=DT-MVP-5004222#prerequisites o https://learn.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/overview#file-based-programs
o你好 dotnet run file, 再见 csproj o 宣布 dotnet run app.cs – 一种更简单的方式来开始使用 C# 和 .NET 10