Skip to content

Latest commit

 

History

History
255 lines (175 loc) · 10.4 KB

episode-061.md

File metadata and controls

255 lines (175 loc) · 10.4 KB

.NET 每周分享第 61 期

卷首语

image

11 月 12 到 14 号是一年一度的 .NET 开发者大会,届时 .NET 9 将会正式发布。到时候会有一系列的现场直播的环节,而且现在向所有开发者征求演讲。

行业资讯

1、Mono 装交给 Wine 项目

image

最近微软将 mono 项目交给了 WineHQ 组织,也就是在 Linux 中著名的 wine 项目的组织。注意这个是支持 .NET Framework 中的 mono 项目,而不是 dotnet/runtime 中的 mono。

2、JetBrain .NET Day

image

2024 年 Jetbrains .NET Day 会在 9 月 25, 26 号举办,目前的演讲主题已经确定:

25 号

– Not Your Father’s ReSharper by Andrew Karpov

– Crafting Blazor Components With Precision and Assurance by Mariekie Coetzee

– A Homage to the Good Old MVC by Alexander Zeitler

– Overcoming Broken Window Syndrome: Code Verification Techniques for .NET Developers by Gael Fraiteur

– Enhancing ASP.NET Core Razor Pages With HTMX: A Simplicity-First Approach by Chris Woodruff

– No More SQLite – How to Write Tests With EF Core Using Testcontainers by Daniel Ward

26 号

– Building Functional DSLs for Life-Saving Applications by Roman Provazník

– Pushing ‘await’ to the Limits by Konstantin Saltuk

– Functional Programming Made Easy in C# With Language Extensions by Stefano Tempesta

– Into the Rabbit Hole of Blazor Wasm Hot Reload by Andrii Rublov

– Orchestration vs. Choreography: The Good, the Bad, and the Trade-Offs by Laila Bougria

– Contract Testing Made Easy: Mastering Pact for Microservices in C# by Irina Scurtu

– Composing Distributed Applications With .NET Aspire by Cecil Phillip

文章推荐

1、.NET 9 中移除 BinaryFormatter

image

由于安全方面的要求,从一个二进制文件反序列化成个对象是危险的,因为攻击者可以替换文件的内容,从而在反序列化的时候,注入攻击代码。所以在 .NET 9 中移除了 BinaryFormatter 的实现,而 .NET Framework 不受影响。 解决办法有两个

  1. 使用 System.Runtime.Serialization.Formatters 包,其包含了原本的实现
  2. 使用其他反序列化工具

2、Visual Studio 中的新特性

image

Visual Studio 2022 v17.11 增加了如下的特性

  1. Search 功能可以限制查询的范围
  2. VS Code 同意快捷键: Ctrl+/ 注释,Ctrl+Shift+P 打开控制面板
  3. *.vsconfig 文件支持
  4. Authentication 功能加强
  5. Teams 开发套件模板

3、Aspire 介绍

Scott Hunter 在 NDC 会议长介绍了 Aspire 。主要包含以下几点

  • 弹性: 最早在 ASP.NET Core 3.0 中引入,Aspire 增强了应用程序的弹性,使其能够优雅地处理云相关的故障(如间歇性失败)。
  • 可观测性: Aspire 内置对 OpenTelemetry 的支持,提供了应用性能和错误的全面洞察。
  • 可扩展性: Aspire 轻松管理本地和云端的资源(如容器),简化了部署过程。

在演示与实际应用, Scott 展示了一个中间件,它随机导致应用程序失败,以展示 Aspire 的弹性功能如何确保应用程序继续运行。 Aspire 引入了服务发现,自动管理云部署中的 IP 地址和端口。Aspire 提供了一个仪表盘,用于本地和云端监控应用健康状况,并跟踪错误和性能指标。Aspire 支持部署到多个云平台,包括 Azure 和 AWS。它抽象了跨云平台管理基础设施的复杂性。

4、使用 CollectionsMarshal 访问 Dictionary

使用 CollectionMarshal 可以提高访问集合类型的性能,比如以 Dictionary 为例

  • GetValueRefOrAddDefault

如果字典至类型为 Struct 类型, 那么可以通过这个方法判断是否存在,如果不存在,可以创建一个这个 key 指向的值的引用

static readonly Dictionary<Guid, string> s_Dico1 = new();
[Benchmark]
public void CreateValIfKeyNotInDico() {
  var key = Guid.NewGuid();
  if (!s_Dico1.ContainsKey(key)) {
    // Create the object to be used as key's value
    // because the key is not present in the dictionary
    string val = key.ToString();
    s_Dico1.Add(key, val);
  }
}

static readonly Dictionary<Guid, string> s_Dico2 = new();
[Benchmark]
public void CreateValIfKeyNotInDico_Faster() {
  var key = Guid.NewGuid();
  ref string pointerToValLocation =
      ref CollectionsMarshal.GetValueRefOrAddDefault(s_Dico2, key,
                                                     out bool exists);
  if (!exists) {
    // Create the object to be used as key's value
    // because the key is not present in the dictionary
    var val = key.ToString();
    pointerToValLocation = val;
  }
}
Method Mean Error StdDev Gen0 Gen1 Allocated
CreateValIfKeyNotInDico 527.0 ns 2,118.9 ns 116.1 ns 0.0095 0.0086 96 B
CreateValIfKeyNotInDico_Faster 452.9 ns 1,859.4 ns 101.9 ns 0.0100 0.0095 96 B
  • GetValueRefOrNullRef

第二种方式是获取值的一个引用,方便修改和读取

static readonly Guid s_Guid = Guid.NewGuid();

static readonly Dictionary<Guid, int> s_Dico1 = new() { { s_Guid, 0 } };

[Benchmark]
public void StructValueInDico() {
  for (int i = 0; i < 1000; i++) {
    s_Dico1[s_Guid] += 1;
  }
}

static readonly Dictionary<Guid, int> s_Dico2 = new() { { s_Guid, 0 } };
[Benchmark]
public void StructValueInDico_Faster() {
  for (int i = 0; i < 1000; i++) {
    ref int pointerToValLocation =
        ref CollectionsMarshal.GetValueRefOrNullRef(s_Dico2, s_Guid);
    // if(!Unsafe.IsNullRef(pointerToValLocation))
    pointerToValLocation++;
  }
}
Method Mean Error StdDev Allocated
StructValueInDico 7.463 us 2.470 us 0.1354 us -
StructValueInDico_Faster 3.069 us 1.018 us 0.0558 us -

5、.NET 开源贡献者名单

image

随着 .NET 开源,越来越多的开发者参与进来,并且做出贡献,该网页可以查看每个 .NET 开源依赖所有的开发者。

开源项目

1、Grok.net

image

Gork.net 借助正则表达式,可以帮助我们很方便的在一些非结构化数据中找到结构化数据。

Grok grok = new Grok("%{MONTHDAY:month}-%{MONTHDAY:day}-%{MONTHDAY:year} %{TIME:timestamp};%{WORD:id};%{LOGLEVEL:loglevel};%{WORD:func};%{GREEDYDATA:msg}");

string logs = @"06-21-19 21:00:13:589241;15;INFO;main;DECODED: 775233900043 DECODED BY: 18500738 DISTANCE: 1.5165
                06-22-19 22:00:13:589265;156;WARN;main;DECODED: 775233900043 EMPTY DISTANCE: --------";

var grokResult = grok.Parse(logs);
foreach (var item in grokResult)
{
    Console.WriteLine($"{item.Key} : {item.Value}");
}

image

2、Sisk

image

Sisk 是除了 ASP.NET Core 之外,又一个网络框架。和 ASP.NET Core 相比,它更加简单,轻便。不到 10 行代码就可以启动一个 Http 服务

using Sisk.Core.Http;

using var app = HttpServer.CreateBuilder(5555).Build();
app.Router.MapGet("/", request => {
    return new HttpResponse("Hello World!");   
});

await app.StartAsync();

3、EntityFramework.Exceptions

image

Entity Framework Core 中,在插入数据的时候如果违反了数据库的条件,就会抛出 DbUpdateException 异常,但是这个有一个问题是,需要从详细的异常信息中找到错误的原因。而且如果换了不同的数据库,有需要重新提取错误信息。EntityFramework.Exceptions 库可以帮助我们统一数据库异常信息。

public class EFCoreContext : DbContext
{
    public EFCoreContext(DbContextOptions<EFCoreContext> options) : base(options)
    {
    }

    public DbSet<Product> Products { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>().HasKey(p => p.Id);
        modelBuilder.Entity<Product>().HasIndex(p => p.Name).IsUnique();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseExceptionProcessor();
    }
}

using var context = new EFCoreContext(options);
context.Products.Add(new Product { Name = "Product 1" , Price = 10});
context.Products.Add(new Product { Name = "Product 1" , Price = 20});

try
{
    context.SaveChanges();
}
catch (UniqueConstraintException  e)
{
    Console.WriteLine($"Unique constraint {e.ConstraintName} violated. Duplicate value for {e.ConstraintProperties[0]}");
}

这里的 UniqueConstraintException 包含了异常的详细信息。除此之外,还支持如下的异常

  • CannotInsertNullException
  • MaxLengthExceededException
  • NumericOverflowException
  • ReferenceConstraintException