强命名

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

强命名的缺点是,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、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 应用程序不需要强命名,默认情况下不应进行。

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

✔️ 请考虑将强命名密钥对(公共 + 专用)添加到源代码管理系统。

通过公开可用的密钥对,开发人员可以使用同一密钥修改和重新编译库源代码。

如果过去曾使用强命名密钥对来在 部分信任方案中授予特殊权限,则不应将其设置为公共。 否则,可能会破坏现有环境。

如果无法签入公钥和私钥对,请签入公钥并使用 公钥签名 进行常规构建。 公共签名仍允许开发人员在大多数情况下重新编译和使用库。

重要

如果需要代码发布者的标识,建议使用 AuthenticodeNuGet 包签名 。 不应将代码访问安全性(CAS)用作安全缓解措施。

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

请详细了解 版本管理以及程序集版本

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

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

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

发布两个包将使您的开发人员生态系统分叉。 此外,如果应用程序最终依赖于这两个包,开发人员可能会遇到类型名称冲突。 从 .NET 来看,它们是不同程序集中的不同类型。