.NET
versioning
assembly
AssemblyVersion
AssemblyFileVersion

What are differences between AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

.NET assemblies carry three distinct version attributes, and each serves a different purpose. AssemblyVersion is the version the runtime uses for binding and strong-name resolution. AssemblyFileVersion is what Windows shows in file properties and is used for build tracking. AssemblyInformationalVersion is a freeform string for human-readable product versioning, such as 2.1.0-beta.3. Understanding when and how to change each one prevents binding failures, stale cache hits, and confusing release labels.

AssemblyVersion: The Runtime Identity

AssemblyVersion is the version that the .NET runtime cares about. It is embedded in the assembly manifest and used during strong-name binding. When a consuming application is compiled against version 1.0.0.0 of a strong-named assembly, the runtime will refuse to load version 2.0.0.0 at run time unless a binding redirect is in place.

csharp
1// In AssemblyInfo.cs (classic .NET Framework)
2[assembly: AssemblyVersion("1.0.0.0")]
3
4// In .csproj (SDK-style projects)
5<PropertyGroup>
6    <AssemblyVersion>1.0.0.0</AssemblyVersion>
7</PropertyGroup>

Key behaviors

  • Format: Strictly Major.Minor.Build.Revision, all numeric. Wildcards like 1.0.* are allowed in classic projects and cause the compiler to auto-generate build and revision numbers.
  • Binding impact: Changing AssemblyVersion on a strong-named assembly is a breaking change. Every consuming project must recompile or add a binding redirect.
  • Default: If omitted in an SDK-style project, defaults to 1.0.0.0.

Because changing this version forces all consumers to update, the common practice is to change AssemblyVersion only for major or breaking releases and keep it stable across minor updates and patches.

AssemblyFileVersion: The Build Identifier

AssemblyFileVersion maps to the Win32 file version resource. It appears in the "Details" tab of file properties on Windows. The .NET runtime does not use this version for binding or loading, so changing it never breaks consumers.

csharp
1// In AssemblyInfo.cs
2[assembly: AssemblyFileVersion("1.2.345.0")]
3
4// In .csproj
5<PropertyGroup>
6    <FileVersion>1.2.345.0</FileVersion>
7</PropertyGroup>

Key behaviors

  • Format: Same four-part numeric format as AssemblyVersion.
  • No binding impact: Changing this version does not require recompilation of consuming assemblies.
  • Common use: Incremented on every CI build. The build number or commit counter is often placed in the third or fourth position, giving each binary a unique identifier for traceability.

If AssemblyFileVersion is not specified, it defaults to the value of AssemblyVersion.

AssemblyInformationalVersion: The Product Label

AssemblyInformationalVersion is a freeform string intended for display. It can contain any text, including semantic version suffixes, branch names, or commit hashes. NuGet uses this attribute as the package version when no explicit PackageVersion is set.

csharp
1// In AssemblyInfo.cs
2[assembly: AssemblyInformationalVersion("2.1.0-beta.3+build.482")]
3
4// In .csproj
5<PropertyGroup>
6    <InformationalVersion>2.1.0-beta.3+build.482</InformationalVersion>
7</PropertyGroup>

Key behaviors

  • Format: No restrictions. Alphanumeric strings, hyphens, dots, and plus signs are all valid. Semantic versioning strings like 1.0.0-rc.1+sha.abc1234 fit naturally here.
  • No binding impact: The runtime ignores this attribute entirely.
  • Visible in: Application.ProductVersion in WinForms, FileVersionInfo.ProductVersion in reflection, and the "Product version" field in Windows file properties.

If not specified, it defaults to the value of AssemblyVersion.

Comparison Table

AttributeFormatUsed by RuntimeAffects BindingCommon Change FrequencyVisible In
AssemblyVersionMajor.Minor.Build.Revision (numeric)YesYes (strong name)Major releases onlyAssembly manifest, GAC
AssemblyFileVersionMajor.Minor.Build.Revision (numeric)NoNoEvery buildWindows file properties
AssemblyInformationalVersionFreeform stringNoNoEvery releaseNuGet, product dialogs

Practical Versioning Strategies

Strategy 1: Lock AssemblyVersion, increment the others

This approach minimizes binding pain. AssemblyVersion stays at 1.0.0.0 across all 1.x releases. AssemblyFileVersion increments with each build. AssemblyInformationalVersion reflects the semantic version.

xml
1<PropertyGroup>
2    <AssemblyVersion>1.0.0.0</AssemblyVersion>
3    <FileVersion>1.3.$(BuildNumber).0</FileVersion>
4    <InformationalVersion>1.3.0-preview.2</InformationalVersion>
5</PropertyGroup>

This is the strategy used by many large .NET libraries, including Newtonsoft.Json.

Strategy 2: Increment all three together

Simpler to reason about but creates binding redirect overhead for strong-named assemblies. Works well for applications (EXEs) that do not have external consumers.

xml
1<PropertyGroup>
2    <Version>2.4.1</Version>
3    <!-- This sets all three attributes to 2.4.1 -->
4</PropertyGroup>

Strategy 3: CI-driven with commit metadata

Modern CI pipelines often stamp the informational version with the Git commit hash for full traceability:

xml
1<PropertyGroup>
2    <AssemblyVersion>3.0.0.0</AssemblyVersion>
3    <FileVersion>3.1.$(BuildId).0</FileVersion>
4    <InformationalVersion>3.1.0+sha.$(GitCommitHash)</InformationalVersion>
5</PropertyGroup>

Reading Version Attributes at Runtime

You can retrieve all three versions programmatically:

csharp
1using System.Diagnostics;
2using System.Reflection;
3
4var assembly = typeof(Program).Assembly;
5
6// AssemblyVersion
7var asmVersion = assembly.GetName().Version;
8Console.WriteLine($"AssemblyVersion: {asmVersion}");
9
10// AssemblyFileVersion
11var fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location);
12Console.WriteLine($"FileVersion: {fileVersionInfo.FileVersion}");
13
14// AssemblyInformationalVersion
15var infoVersion = assembly
16    .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
17    ?.InformationalVersion;
18Console.WriteLine($"InformationalVersion: {infoVersion}");

This is useful for logging the exact build running in production or displaying version information in an "About" dialog.

SDK-Style Project Property Mapping

In modern SDK-style .csproj files, the MSBuild properties map to assembly attributes as follows:

MSBuild PropertyAssembly AttributeFalls Back To
<AssemblyVersion>AssemblyVersionAttribute1.0.0.0
<FileVersion>AssemblyFileVersionAttributeAssemblyVersion value
<InformationalVersion>AssemblyInformationalVersionAttributeAssemblyVersion value
<Version>Sets all three if individual properties are not specified1.0.0

The <Version> property is a convenience shortcut. Setting <Version>2.0.0</Version> populates all three attributes, but any individually specified property takes precedence.

Common Pitfalls

Incrementing AssemblyVersion on every build for strong-named assemblies. This forces all consumers to recompile or add binding redirects on every release. Keep AssemblyVersion stable within a major version and increment FileVersion instead.

Confusing AssemblyVersion with NuGet package version. NuGet uses AssemblyInformationalVersion (or the <Version> property) for the package version, not AssemblyVersion. A library with AssemblyVersion 1.0.0.0 and InformationalVersion 1.5.0 publishes as NuGet version 1.5.0.

Omitting FileVersion in CI builds. Without an explicit FileVersion, it defaults to AssemblyVersion, making it impossible to distinguish between two builds of the same assembly version. Always set FileVersion to include a build number for traceability.

Using non-numeric characters in AssemblyVersion. The runtime requires strictly numeric Major.Minor.Build.Revision values. Putting 1.0.0-beta in AssemblyVersion causes a build error. Pre-release labels belong in InformationalVersion.

Not setting GenerateAssemblyInfo to false when using AssemblyInfo.cs. In SDK-style projects, the build system auto-generates assembly attributes. If you also have a manual AssemblyInfo.cs, you get duplicate attribute errors. Either delete the manual file or set <GenerateAssemblyInfo>false</GenerateAssemblyInfo>.

Summary

  • AssemblyVersion is the identity version used by the runtime for binding. Change it only for breaking or major releases.
  • AssemblyFileVersion is the build-level identifier shown in Windows file properties. Increment it on every CI build for traceability.
  • AssemblyInformationalVersion is a freeform product version string. Use it for semantic versions, pre-release labels, and commit metadata.
  • In SDK-style projects, the <Version> property sets all three unless individual properties override it.
  • Keep AssemblyVersion stable to avoid unnecessary binding redirects, and use FileVersion and InformationalVersion for granular build and release tracking.

Course illustration
Course illustration

All Rights Reserved.