Nuget pack does not honor number of digits on assembly version

半城伤御伤魂 提交于 2019-12-05 07:06:42

In the Creating and Publishing a Package it is stated that NuGet uses AssemblyVersionAttribute attribute when the token $version$ is used.
Digging into NuGet source code, I've found that it's not as straight forward as one might think.

NuGet uses reflection to get your library's version. AssemblyName.Version to be exact. Since all components of the version must be integers greater than or equal to zero (see AssemblyName.Version), the version presented is 1.0.0.0 (in your case) rather than 1.0.0 as declared in your AssemblyVersion attribute.

Possible solution
The Nuspec Reference page adds more information next to the $version$ token. It mentions AssemblyInformationalVersionAttribute attribute will get precedence over AssemblyVersionAttribute. Using it will solve your problem.

Digging deeper
You might wonder why would AssemblyInformationalVersionAttribute work and AssemblyVersionAttribute won't?

The answer to that question is that NuGet uses CustomAttributeData.GetCustomAttributes(Assembly) function to retrieve the attributes of your library, before it uses Assembly.Version. The above function will not list AssemblyVersionAttribute, yet it will list AssemblyInformationalVersionAttribute if it was used on the assembly. Only then, if AssemblyInformationalVersionAttribute wasn't found, Assembly.Version will be used.

EDIT:
Relevant NuGet source code:
NuGet uses the following code to get the assembly version (if AssemblyInformationalVersionAttribute wasn't found):

Assembly assembly = Assembly.ReflectionOnlyLoadFrom(path);
AssemblyName assemblyName = assembly.GetName();
...
version = new SemanticVersion(assemblyName.Version);

The problem starts with assembly.GetName() as it creates and initializes AssemblyName with relevant parameters, including the version.
(That code can be found in AssemblyMetadataExtractor class, under public AssemblyMetadata GetMetadata(string path) function.)

Ran into this same problem and solved it using the "-version" attribute of nuget. It overrides the version from the nuspec file. Works wonderfully for semantic versioning.

Based on the above, I'm guessing it wasn't available at the time this discussion was started.

NuGet seems to be using [assembly: AssemblyInformationalVersion()] as a version, not AssemblyVersion nor AssemblyFileVersion

Set AssemblyInformationalVersion to 2 or 3 components and nuget will package it exactly as you specified

I'd also set AssemblyVersion to some auto-incremented thing since it's used by .NET and based on my MSBuild experience it's safer to force it to think version changes all the time so it does not try to be smart about it

[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyInformationalVersion("1.0")]

Results in

Project.1.0.nupkg

Containing

Project.dll

with metadata (as reported by ILSpy) ..., Version=1.0.6246.25505, Culture=neutral, PublicKeyToken=null...

So you get nice nuget version and fool proof assembly version (always changing so no weird caching during builds if package version stays the same, say for local testing)

Source

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!