We can define versions on our .NET Core applications, but how to get the version at runtime? There are several ways to do it.
First, let's see a typical .NET Core project file with versioning. We can define the version numbers for AssemblyVersion, FileVersion and Version in the project file (.csproj).
The AssemblyVersion and FileVersion attributes must be in format of "major[.minor[.build[.revision]]]" or you will get a compile time error (CS7034).
The attribute Version can contain customized strings, like a surfix of "-xyz" as shown below:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AssemblyVersion>1.1.1.1</AssemblyVersion>
<FileVersion>2.2.2.2</FileVersion>
<Version>3.3.3.3-xyz</Version>
</PropertyGroup>
</Project>
In compile time, this will generate a class file:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("2.2.2.2")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("3.3.3.3-xyz")]
[assembly: System.Reflection.AssemblyProductAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyTitleAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.1.1.1")]
// Generated by the MSBuild WriteCodeFragment class.
With this in mind, lets see how can we read these values in runtime.
1. AssemblyVersion
There are two ways to get the AssemblyVersion
If you are not getting this in a static method, you can use
GetType().Assembly.GetName().Version.ToString()
But if you need to use this in a static method, you may have to create a class like this:
class Foo
{
public string GetAssemblyVersion()
{
return GetType().Assembly.GetName().Version.ToString();
}
}
and then:
new Foo().GetAssemblyVersion()
This is ugly code. So we have another way to read the AssemblyVersion
Assembly.GetEntryAssembly().GetName().Version
This can be used in static and non-static methods.
Both of these two methods will return 1.1.1.1
2. FileVersion
We can use GetCustomAttribute extension method to get the AssemblyFileVersionAttribute and read the Version attribute.
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version
It will return 2.2.2.2
3. Version
Similar to FileVersion but this time we will use AssemblyInformationalVersionAttribute
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion
It will return 3.3.3.3
4. Complete Sample Code
using System;
using System.Reflection;
namespace netcoreappver
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"GetType().Assembly.GetName().Version: " +
$"{new Foo().GetAssemblyVersion()}");
Console.WriteLine($"Assembly.GetEntryAssembly().GetName().Version: " +
$"{Assembly.GetEntryAssembly().GetName().Version}");
Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version:" +
$"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version}");
Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion:" +
$"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute> ().InformationalVersion}");
Console.ReadKey();
}
}
class Foo
{
public string GetAssemblyVersion()
{
return GetType().Assembly.GetName().Version.ToString();
}
}
}
5. Which version should I use?
According to this thread:
AssemblyVersion
Where other assemblies that reference your assembly will look. If this number changes, other assemblies have to update their references to your assembly.
AssemblyFileVersion
Used for deployment. You can increase this number for every deployment. It is used by setup programs. Use it to mark assemblies that have the same AssemblyVersion, but are generated from different builds.
In Windows, it can be viewed in the file properties.
If possible, let it be generated by MSBuild. The AssemblyFileVersion is optional. If not given, the AssemblyVersion is used.
I use the format: major.minor.revision.build, where I use revision for development stage (Alpha, Beta, RC and RTM), service packs and hot fixes.
AssemblyInformationalVersion
The Product version of the assembly. This is the version you would use when talking to customers or for display on your website. This version can be a string, like '1.0 Release Candidate'.
Thank you good sir!
Thanks for this!
I'm getting n exception of type 'System.NullReferenceException' when I try to get GetCustomAttributes such as AssemblyInformationalVersionAttribute. Any ideas why or work-arounds?
.NET Core SDK (reflecting any global.json): Version: 2.1.803
Very useful post! Thank you.