在公司外,我们使用NuGet来版本化我们的内部库。每次提交到库都会触发构建服务器,该服务器会生成一个新的NuGet包并将其上传到我们的内部源。
这对我们来说效果很好,但我们经常遇到WinForms设计器的问题,它会拒绝加载带有如下错误消息的表单:
Die Datei oder Assembly“UILib,Version = 1.0.0.906,Culture = neutral,PublicKeyToken = null”oder abineabhängigkeitdavonwurde nicht gefunden。 Das System kann die angegebene Datei nicht finden。
(粗略:文件或程序集“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的所有更改都是向后兼容的,我们也没有这些库的强名称。事实上,构建和运行App工作正常。但是设计师现在已经破坏了受影响的表单并显示了我上面提到的错误消息。
要解决此问题,我们还必须更新ProductUILib的NuGet包,以便依次针对最新的UILib构建,然后再次更新App的依赖项以获取新的ProductUILib。然而,这很快就会变得乏味,特别是有更多的库和依赖项。
我在VS 2010和最新的VS 2013中进行了测试,新版本显示了完全相同的行为。
您对我们如何避免此问题有任何建议吗?
答案 0 :(得分:1)
我们设法通过更改使用AssemblyVersion
,AssemblyFileVersion
和AssemblyInformationalVersion
的策略来解决问题。
我们会在每次构建时自动生成版本号的最后一部分,方法是将其设置为当前的SVN版本号。生成的版本号(例如1.0.0.906)曾用于AssemblyVersion
和AssemblyFileVersion
。
设计师显然对AssemblyVersion
的不匹配产生问题,因为具有不同AssemblyVersion
的程序集被认为是不兼容的。但是,没有强名称的程序集的正常加载过程并不介意不匹配,因此构建和运行程序可以正常工作。所以设计师只是有点挑剔。
解决方案是使用AssemblyVersion
的固定值,我们只会在更改时更新。生成的版本号现在同时转到AssemblyFileVersion
和AssemblyInformationalVersion
。最后一个是重要的,因为NuGet将始终从AssemblyVersion
填充其.nuspec $ version $占位符,除非存在AssemblyInformationalVersion
以覆盖它,并且我们希望生成用于我们的NuGet包的版本号。
总结如下:
AssemblyVersion
以便更改AssemblyInformationalVersion
作为应该进入NuGet包的号码