AssemblyMetadata by Benjamin Abt
NuGet / site data
Details
Info
Name: AssemblyMetadata
Assembly Metadata Information
Author: Benjamin Abt
NuGet: https://www.nuget.org/packages/AssemblyMetadata/
You can find more details at https://github.com/BenjaminAbt/AssemblyMetadata
Author
Benjamin Abt

Original Readme
AssemblyMetadata

| Framework | .NET 10 | .NET 9 | .NET 8 | .NET Standard / 4.6.2+ |
|---|---|---|---|---|
| Supported | ✅ | ✅ | ✅ | ✅ |
A Roslyn incremental source generator that embeds build-time metadata - timestamp, date and time components - as compile-time constants directly into your assembly. Zero runtime overhead. No reflection. No configuration required.
Table of Contents
- Why AssemblyMetadata?
- Installation
- Quick Start
- API Reference
- Usage Examples
- Target Frameworks
- License
Why AssemblyMetadata?
Knowing when an assembly was built is useful for diagnostics, "About" screens, deployment validation, and telemetry. The traditional approaches all have trade-offs:
| Approach | Runtime cost | Dependency | Works with AOT? |
|---|---|---|---|
Read AssemblyInformationalVersion attribute | Reflection at runtime | None | ⚠️ Limited |
| Embed a resource file with the date | Resource deserialization | Build task | ⚠️ Yes |
| AssemblyMetadata (this package) | Zero - values are const | None (analyzer only) | ✅ Yes |
AssemblyMetadata solves this differently:
- Compile-time constants - values are
const, so the JIT can inline and dead-code-eliminate them - Zero-cost access - reading the timestamp costs nothing beyond a register load
- No dependencies at runtime - the NuGet package ships as a Roslyn source generator; nothing is added to your runtime dependency graph
- NativeAOT-compatible -
constfields have no reflection or dynamic dispatch - Incremental generator - uses the modern Roslyn
IIncrementalGeneratorAPI, so the generator only re-runs when the compilation changes, keeping build times fast
Installation
Add the package to any project that needs build metadata:
<PackageReference Include="AssemblyMetadata"
Version="LATEST_VERSION"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
OutputItemType="Analyzer"andReferenceOutputAssembly="false"are required. They instruct MSBuild to load the package as a Roslyn source generator (not a regular assembly reference), producing zero runtime dependencies.
Quick Start
After adding the package, the generated class AssemblyMetadataInfo is immediately available
anywhere in your project under the BenjaminAbt.AssemblyMetadata namespace:
using BenjaminAbt.AssemblyMetadata;
// ISO 8601 UTC timestamp of the build
string timestamp = AssemblyMetadataInfo.BuildInfo.BuildTimestamp;
// → "2026-03-02T14:35:07.1234567+00:00"
Console.WriteLine($"Built on {AssemblyMetadataInfo.BuildInfo.BuildDateYear}-"
+ $"{AssemblyMetadataInfo.BuildInfo.BuildDateMonth:D2}-"
+ $"{AssemblyMetadataInfo.BuildInfo.BuildDateDay:D2} "
+ $"at {AssemblyMetadataInfo.BuildInfo.BuildTimeHour:D2}:"
+ $"{AssemblyMetadataInfo.BuildInfo.BuildTimeMinute:D2}:"
+ $"{AssemblyMetadataInfo.BuildInfo.BuildTimeSecond:D2} UTC");
No additional configuration, properties, or attributes are required.
API Reference
The generator produces a single file (AssemblyMetadataInfo.gen.cs) in the
BenjaminAbt.AssemblyMetadata namespace. All members are public const.
######### AssemblyMetadataInfo.BuildInfo
| Member | Type | Description |
|---|---|---|
BuildTimestamp | string | Build time as a UTC ISO 8601 round-trip string ("o" format specifier) |
BuildFileTimeUtc | long | Build time as a Windows FileTime - 100-nanosecond intervals since 1601-01-01T00:00:00Z |
BuildDateYear | int | Year component of the UTC build date |
BuildDateMonth | int | Month component of the UTC build date (1–12) |
BuildDateDay | int | Day component of the UTC build date (1–31) |
BuildTimeHour | int | Hour component of the UTC build time (0–23) |
BuildTimeMinute | int | Minute component of the UTC build time (0–59) |
BuildTimeSecond | int | Second component of the UTC build time (0–59) |
Usage Examples
######### Display Build Timestamp
using BenjaminAbt.AssemblyMetadata;
Console.WriteLine(AssemblyMetadataInfo.BuildInfo.BuildTimestamp);
// → 2026-03-02T14:35:07.1234567+00:00
######### Parse into DateTimeOffset
Use the "o" round-trip format specifier to parse the stored constant back into a
DateTimeOffset - the same format used by the generator:
using System;
using BenjaminAbt.AssemblyMetadata;
DateTimeOffset buildOn = DateTimeOffset.ParseExact(
AssemblyMetadataInfo.BuildInfo.BuildTimestamp, "o", null);
Console.WriteLine($"Built {(DateTimeOffset.UtcNow - buildOn).Days} days ago.");
######### Reconstruct from FileTime (zero-allocation)
BuildFileTimeUtc lets you reconstruct a DateTimeOffset without any string parsing:
using System;
using BenjaminAbt.AssemblyMetadata;
DateTimeOffset buildOn =
DateTimeOffset.FromFileTime(AssemblyMetadataInfo.BuildInfo.BuildFileTimeUtc);
This is the fastest way to get a DateTimeOffset representation of the build time.
######### Use Individual Components
The integer constants allow zero-allocation formatting and direct numeric comparison:
using BenjaminAbt.AssemblyMetadata;
// Compose a date string without DateTimeOffset overhead
string buildDate =
$"{AssemblyMetadataInfo.BuildInfo.BuildDateYear}-"
+ $"{AssemblyMetadataInfo.BuildInfo.BuildDateMonth:D2}-"
+ $"{AssemblyMetadataInfo.BuildInfo.BuildDateDay:D2}";
// Direct year comparison - no parsing, no allocation
if (AssemblyMetadataInfo.BuildInfo.BuildDateYear < 2025)
Console.WriteLine("Assembly was built before 2025.");
######### Build Age Check
using System;
using BenjaminAbt.AssemblyMetadata;
TimeSpan age = DateTimeOffset.UtcNow
- DateTimeOffset.FromFileTime(AssemblyMetadataInfo.BuildInfo.BuildFileTimeUtc);
if (age.TotalDays > 30)
Console.WriteLine($"Warning: this build is {(int)age.TotalDays} days old.");
######### Health Endpoint
Expose the build timestamp in an ASP.NET Core health or info endpoint:
using BenjaminAbt.AssemblyMetadata;
app.MapGet("/info", () => new
{
BuildTimestamp = AssemblyMetadataInfo.BuildInfo.BuildTimestamp,
BuildYear = AssemblyMetadataInfo.BuildInfo.BuildDateYear,
BuildMonth = AssemblyMetadataInfo.BuildInfo.BuildDateMonth,
BuildDay = AssemblyMetadataInfo.BuildInfo.BuildDateDay,
});
License
Please donate - if possible - to institutions of your choice such as child cancer aid, children's hospices, etc. Thanks!
About
Generate date time based metadata for assemblies.
How to use
Example (source csproj, source files)
- CSharp Project
- Program.cs
This is the CSharp Project that references AssemblyMetadata
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AssemblyMetadata" Version="2.0.16" OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of AssemblyMetadata in Program.cs
Console.WriteLine(BenjaminAbt.AssemblyMetadata.AssemblyMetadataInfo.BuildInfo.BuildDateYear);
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- AssemblyMetadataInfo.gen.cs
// <auto-generated />
namespace BenjaminAbt.AssemblyMetadata
{
internal static class AssemblyMetadataInfo
{
/// <summary>Contains compile-time build metadata constants.</summary>
internal static class BuildInfo
{
/// <summary>Build time as UTC ISO 8601 string.</summary>
public const string BuildTimestamp = "2026-04-03T05:50:57.6130105+00:00";
/// <summary>Build time as Windows FileTime (100-ns intervals since 1601-01-01 UTC).</summary>
public const long BuildFileTimeUtc = 134196690576130105L;
/// <summary>Year component of the build date (UTC).</summary>
public const int BuildDateYear = 2026;
/// <summary>Month component of the build date (UTC).</summary>
public const int BuildDateMonth = 4;
/// <summary>Day component of the build date (UTC).</summary>
public const int BuildDateDay = 3;
/// <summary>Hour component of the build time (UTC, 24-hour).</summary>
public const int BuildTimeHour = 5;
/// <summary>Minute component of the build time (UTC).</summary>
public const int BuildTimeMinute = 50;
/// <summary>Second component of the build time (UTC).</summary>
public const int BuildTimeSecond = 57;
}
}
}
Useful
Download Example (.NET C#)
Share AssemblyMetadata
https://ignatandrei.github.io/RSCG_Examples/v2/docs/AssemblyMetadata
Category "EnhancementProject" has the following generators:
1 AssemblyMetadata
2026-04-02
2 AssemblyVersionInfo
2025-07-28
3 AutoInvoke.Generator
2024-03-03
4 AutoSpectre
2024-02-24
5 BuildInfo
2024-01-20
6 Credfeto.Version.Information.Generator
2024-11-05
7 Larcanum.GitInfo
2025-01-17
8 LinqGen.Generator
2024-03-04
9 Pekspro.BuildInformationGenerator
2024-07-19
10 PlantUmlClassDiagramGenerator
2024-02-20
11 RSCG_AMS
2023-04-16
12 RSCG_ExportDiagram
2024-08-01
13 RSCG_FunctionsWithDI
2023-04-16
14 RSCG_NameGenerator
2024-08-25
15 RSCG_TimeBombComment
2023-04-16
16 RSCG_Wait
2024-02-21
17 ShadowWriterProjectInfo
2025-07-27
18 ThisAssembly
2023-04-16
19 ThisAssembly.Constants
2024-07-18
20 ThisAssembly.Metadata
2024-07-20