强命名

强命名指使用密钥对程序集进行签名,从而生成强名称程序集。 程序集具有强名称时,将基于名称和程序集版本号创建唯一标识,并有助于防止发生程序集冲突。

强命名的缺点是,一旦程序集具有强名称,Windows 上的 .NET Framework 就会严格加载程序集。 强名称程序集引用必须与已加载的程序集版本完全匹配,强制开发人员在使用程序集时配置绑定重定向

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

当 .NET 开发人员抱怨强命名时,通常抱怨的是严格的程序集加载。 幸运的是,此问题独立于 .NET Framework。 .NET 5+、.NET Core、Xamarin、UWP 和大多数其他 .NET 实现没有严格的程序集加载(强命名的主要缺点)。

.NET Framework 强命名的一个重要方面是它传播性强:强名称程序集只能引用其他强名称程序集。 如果库没有强名称,则需要强命名的 .NET Framework 应用和库无法使用该库。

.NET Framework 上强命名的优点包括:

  1. 程序集可以被引用并由其他强名称程序集使用。
  2. 程序集可以存储在全局程序集缓存 (GAC) 中。
  3. 程序集可以与其他版本的程序集并行加载。 具有插件体系结构的应用程序通常需要并行程序集加载。

强命名在 .NET Core/5+ 上没有优势。 C# 编译器为引用非强名称程序集的强名称程序集生成 CS8002 警告。 对于仅面向 .NET Core/5+ 的库,可以禁止显示此警告。

创建强名称 .NET 库

如果开源 .NET 库的目标包括 .NET Framework 或 .NET Standard,则应为其强命名。 仅面向 .NET Core/5+ 的库不需要强命名。

注意

本指南特定于公开分布的 .NET 库,如 NuGet.org 上发布的 .NET 库。强命名不是大多数 .NET 应用程序所必需的,默认情况下不得执行强命名。

✔️ 请考虑强命名库的程序集。

✔️ 请考虑将强命名密钥添加到源代码管理系统。

公开提供的密钥可让开发人员修改库源代码并使用相同的密钥进行重新编译。

如果强命名密钥过去用于在部分信任的方案中授予特殊权限,则不得公开该强命名密钥。 或者,可能会破坏现有环境。

重要

需要了解代码发布者的身份时,建议使用验证码NuGet 包签名。 代码访问安全性 (CAS) 不得用作安全缓解。

✔️ 请考虑仅在主版本发生更改时递增程序集版本,以帮助用户减少绑定重定向和更新频率。

详细了解版本控制和程序集版本

❌ 请勿添加、删除或更改强命名密钥。

修改程序集的强命名密钥会更改程序集的标识并破坏使用该标识的已编译代码。 有关详细信息,请参阅二进制重大更改

❌ 请勿发布库的强名称和非强名称版本。 例如,Contoso.ApiContoso.Api.StrongNamed

发布两个包会为开发人员生态系统创建分支。 此外,如果应用程序依赖于这两个包,则开发人员可能会遇到类型名称冲突。 就 .NET 而言,它们是不同程序集中的不同类型。