如何使用NuGet工作流避免程序集版本不匹配导致的Winforms designer错误

如何使用NuGet工作流避免程序集版本不匹配导致的Winforms designer错误,winforms,visual-studio,dependencies,nuget,designer,Winforms,Visual Studio,Dependencies,Nuget,Designer,在我们公司,我们使用NuGet来版本我们的内部库。对库的每一次提交都会触发构建服务器,它会生成一个新的NuGet包并将其上传到我们的内部提要 这对我们来说非常有效,但我们经常遇到WinForms designer的问题,它会拒绝加载带有以下错误消息的表单: App ----> ProductUILib ----> UILib | ^ ------------------------------| 模具日期顺序程序集“UIL

在我们公司,我们使用NuGet来版本我们的内部库。对库的每一次提交都会触发构建服务器,它会生成一个新的NuGet包并将其上传到我们的内部提要

这对我们来说非常有效,但我们经常遇到WinForms designer的问题,它会拒绝加载带有以下错误消息的表单:

App ----> ProductUILib ----> UILib
 |                             ^
 ------------------------------|
模具日期顺序程序集“UILib,版本=1.0.0.906,区域性=中立,PublicKeyToken=null”顺序为davon wurde nicht gefunden。这套系统不适用于任何数据

(大概是:找不到文件或程序集“UILib,Version=1.0.0.906,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到此文件。)

不过这只是一个设计器问题-应用程序将毫无问题地构建并按预期运行

这就是问题所在,但现在您需要一些有价值的上下文来理解它。我试图打开的表单是应用程序的一部分(我们称之为App),它包含一个UserControl,它是特定于产品的UI库(ProductUILib)的一部分。该库反过来引用我们的通用UI库(UILib)。然而,应用程序本身也直接依赖于UILib

UILib和ProductUILib都是通过它们自己的NuGet包提供的。因此,简化的依赖关系图如下所示:

App ----> ProductUILib ----> UILib
 |                             ^
 ------------------------------|
只要ProductUILib和App引用同一版本的UILib(比如1.0.0.906),一切正常。然而,如果我修改UILib,然后在App中更新我的NuGet依赖项,App将获取并引用UILib的最新版本(比如1.0.0.932)。ProductUILib是针对旧的UILib构建的,但这应该没问题,因为对UILib的所有更改都是向后兼容的,而且我们也没有这些库的强名称。事实上,构建和运行应用程序工作正常。但是现在受影响表单的设计器已被破坏,并显示我上面提到的错误消息

为了解决这个问题,我们还必须更新ProductUILib的NuGet包,这样它就可以根据最新的UILib进行构建,然后再次更新应用程序的依赖项以获得新的ProductUILib。但这很快就会变得单调乏味,尤其是对于更多的库和依赖项

我在VS 2010和最新的VS 2013中进行了测试,新的VS显示了完全相同的行为


您对如何避免此问题有何建议?

我们通过更改使用
AssemblyVersion
AssemblyFileVersion
assemblyInformationVersion
的策略,成功地解决了此问题

通过将版本号设置为当前的SVN修订号,我们会在每个构建中自动生成版本号的最后一部分。此生成的版本号(例如1.0.0.906)用于进入
AssemblyVersion
AssemblyFileVersion

设计师显然对
AssemblyVersion
的不匹配表示异议,因为具有不同
AssemblyVersion
的程序集被视为不兼容。但是,没有强名称的程序集的正常加载过程并不介意不匹配,因此构建和运行程序是可行的。所以设计师只是有点挑剔

解决方案是为
AssemblyVersion
使用一个固定值,我们只会在发生重大更改时更新该值。生成的版本号现在会同时转到
AssemblyFileVersion
AssemblyInformationalVersion
。最后一个很重要,因为NuGet将始终从
AssemblyVersion
填充其.nuspec$version$占位符,除非存在
AssemblyInformationalVersion
来覆盖它,并且我们希望生成的版本号用于NuGet包

总而言之:

  • 仅更新
    AssemblyVersion
    以中断更改
  • 使用
    AssemblyInformationalVersion
    获取应放入NuGet软件包中的数字