Skip to main content

AssemblyMetadata by Benjamin Abt

NuGet / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

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

Source: https://github.com/BenjaminAbt/AssemblyMetadata

Author

note

Benjamin Abt Alt text

Original Readme

note

AssemblyMetadata

AssemblyMetadata

Main Build NuGet NuGet Downloads License: MIT .NET

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?

Knowing when an assembly was built is useful for diagnostics, "About" screens, deployment validation, and telemetry. The traditional approaches all have trade-offs:

ApproachRuntime costDependencyWorks with AOT?
Read AssemblyInformationalVersion attributeReflection at runtimeNone⚠️ Limited
Embed a resource file with the dateResource deserializationBuild task⚠️ Yes
AssemblyMetadata (this package)Zero - values are constNone (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 - const fields have no reflection or dynamic dispatch
  • Incremental generator - uses the modern Roslyn IIncrementalGenerator API, 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" and ReferenceOutputAssembly="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

MemberTypeDescription
BuildTimestampstringBuild time as a UTC ISO 8601 round-trip string ("o" format specifier)
BuildFileTimeUtclongBuild time as a Windows FileTime - 100-nanosecond intervals since 1601-01-01T00:00:00Z
BuildDateYearintYear component of the UTC build date
BuildDateMonthintMonth component of the UTC build date (1–12)
BuildDateDayintDay component of the UTC build date (1–31)
BuildTimeHourintHour component of the UTC build time (0–23)
BuildTimeMinuteintMinute component of the UTC build time (0–59)
BuildTimeSecondintSecond 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

MIT © BEN ABT

Please donate - if possible - to institutions of your choice such as child cancer aid, children's hospices, etc. Thanks!

About

note

Generate date time based metadata for assemblies.

How to use

Example (source csproj, source files)

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>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

// <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 Nuget GitHub Repo stars 2026-04-02

2 AssemblyVersionInfo Nuget GitHub Repo stars 2025-07-28

3 AutoInvoke.Generator Nuget GitHub Repo stars 2024-03-03

4 AutoSpectre NugetNuget GitHub Repo stars 2024-02-24

5 BuildInfo Nuget GitHub Repo stars 2024-01-20

6 Credfeto.Version.Information.Generator Nuget GitHub Repo stars 2024-11-05

7 Larcanum.GitInfo Nuget GitHub Repo stars 2025-01-17

8 LinqGen.Generator NugetNuget GitHub Repo stars 2024-03-04

9 Pekspro.BuildInformationGenerator Nuget GitHub Repo stars 2024-07-19

10 PlantUmlClassDiagramGenerator NugetNuget GitHub Repo stars 2024-02-20

11 RSCG_AMS Nuget GitHub Repo stars 2023-04-16

12 RSCG_ExportDiagram Nuget GitHub Repo stars 2024-08-01

13 RSCG_FunctionsWithDI Nuget GitHub Repo stars 2023-04-16

14 RSCG_NameGenerator Nuget GitHub Repo stars 2024-08-25

15 RSCG_TimeBombComment Nuget GitHub Repo stars 2023-04-16

16 RSCG_Wait Nuget GitHub Repo stars 2024-02-21

17 ShadowWriterProjectInfo Nuget GitHub Repo stars 2025-07-27

18 ThisAssembly Nuget GitHub Repo stars 2023-04-16

19 ThisAssembly.Constants Nuget GitHub Repo stars 2024-07-18

20 ThisAssembly.Metadata Nuget GitHub Repo stars 2024-07-20

See category

EnhancementProject