Praefixum 2.0.1
dotnet add package Praefixum --version 2.0.1
NuGet\Install-Package Praefixum -Version 2.0.1
<PackageReference Include="Praefixum" Version="2.0.1" />
<PackageVersion Include="Praefixum" Version="2.0.1" />
<PackageReference Include="Praefixum" />
paket add Praefixum --version 2.0.1
#r "nuget: Praefixum, 2.0.1"
#:package Praefixum@2.0.1
#addin nuget:?package=Praefixum&version=2.0.1
#tool nuget:?package=Praefixum&version=2.0.1
Praefixum - Unique ID Generator for .NET
Praefixum is a .NET 10 source generator that emits interceptors for automatic unique ID generation. It enables deterministic, human-friendly identifiers to be generated for method parameters marked with the [UniqueId] attribute.
๐ Features
- Build-time interceptors - Generated code handles IDs without manual wiring
- Deterministic by call site - Same code location generates stable IDs
- Multiple parameter support - Handle multiple
[UniqueId]parameters in a single method - Multiple formats - Support for HTML IDs, GUIDs, timestamps, and hash-based IDs
- Prefix support - Add custom prefixes to generated IDs
- Interceptor-based - Uses .NET 10 preview interceptors for seamless integration
- Thread-safe - Generated IDs are constants, no concurrency issues
- Zero dependencies - Pure source generator implementation
๐ฆ Installation
Install via NuGet Package Manager:
dotnet add package Praefixum
Or via Package Manager Console:
Install-Package Praefixum
๐ฏ Quick Start
1. Define a method with UniqueId parameter
using Praefixum;
public static string CreateButton(
string text,
[UniqueId(UniqueIdFormat.HtmlId)] string? id = null)
{
return $"<button id=\"{id}\">{text}</button>";
}
2. Use the method
// Each call generates a unique ID via the generated interceptor
var button1 = CreateButton("Click me"); // <button id="a1b2c3d4">Click me</button>
var button2 = CreateButton("Submit"); // <button id="x9y8z1w2">Submit</button>
3. Compilation magic โจ
The source generator emits interceptors that replace null [UniqueId] parameters with generated IDs based on the call location.
๐จ Supported ID Formats
| Format | Example | Description |
|---|---|---|
HtmlId |
a1b2c3d4 |
HTML5-compliant ID (starts with letter, 8 characters) |
Guid |
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 |
32-character deterministic GUID (no dashes) |
Timestamp |
1735052327842 |
Unix timestamp in milliseconds |
ShortHash |
YWJjZGVm |
8-character Base64-encoded hash |
๐ Usage Examples
HTML ID Generation
public static string Div(
string content,
[UniqueId(UniqueIdFormat.HtmlId, prefix: "div-")] string? id = null)
{
return $"<div id=\"{id}\">{content}</div>";
}
// Usage
var html = Div("Hello World"); // <div id="div-a1b2c3d4">Hello World</div>
Multiple Parameters
NEW: Praefixum now supports multiple [UniqueId] parameters in a single method!
public static string Form(
[UniqueId(UniqueIdFormat.HtmlId, prefix: "form-")] string? formId = null,
[UniqueId(UniqueIdFormat.HtmlId)] string? nameInputId = null,
[UniqueId(UniqueIdFormat.HtmlId)] string? emailInputId = null,
[UniqueId(UniqueIdFormat.Guid)] string? submitId = null)
{
return $@"
<form id=""{formId}"">
<input id=""{nameInputId}"" name=""name"" type=""text"" />
<input id=""{emailInputId}"" name=""email"" type=""email"" />
<button id=""{submitId}"" type=""submit"">Submit</button>
</form>";
}
// Usage - all IDs are automatically generated and unique
var form = Form();
// Generates: form-x1y2z3w4, a5b6c7d8, e9f0g1h2, i3j4k5l6m7n8o9p0q1r2s3t4u5v6w7x8
Custom Prefixes
public static string Input(
[UniqueId(UniqueIdFormat.HtmlId, prefix: "input-")] string? id = null)
{
return $"<input id=\"{id}\" type=\"text\" />";
}
Different Formats in Same Method
public static string Widget(
[UniqueId(UniqueIdFormat.HtmlId)] string? elementId = null,
[UniqueId(UniqueIdFormat.Timestamp)] string? timestampId = null,
[UniqueId(UniqueIdFormat.Guid)] string? uuid = null)
{
return $@"
<div id=""{elementId}"" data-timestamp=""{timestampId}"" data-uuid=""{uuid}"">
Widget Content
</div>";
}
๐๏ธ How It Works
- Attribute Detection: The source generator scans for methods with
[UniqueId]parameters - Call Site Analysis: Identifies calls to methods with
[UniqueId]parameters - Interceptor Generation: Creates interceptor methods for each call site using .NET 10 preview interceptors
- ID Generation: Generates IDs from call-site location data at build time
- Invocation: The interceptor fills null parameters with literal IDs and calls the original method
Generated Code Example
For this source code:
var form = CreateFormWithMultipleIds(); // Line 42, Column 12
The generator creates an interceptor that:
- Checks if all
[UniqueId]parameters are provided - If any are null, generates unique IDs based on call site + parameter index
- Calls the original method with generated or provided IDs
[InterceptsLocation(1, "D:\\MyProject\\Program.cs(42,12)")]
public static string CreateFormWithMultipleIds_0(
string? formId = null,
string? nameInputId = null,
string? emailInputId = null,
string? submitButtonId = null)
{
// Check if all parameters provided
if (formId != null && nameInputId != null && emailInputId != null && submitButtonId != null)
return OriginalClass.CreateFormWithMultipleIds(formId, nameInputId, emailInputId, submitButtonId);
// Generate IDs for null parameters
var formIdFinal = formId ?? GenerateId("key:0", 1, UniqueIdFormat.HtmlId, "form-");
var nameInputIdFinal = nameInputId ?? GenerateId("key:1", 1, UniqueIdFormat.HtmlId, null);
var emailInputIdFinal = emailInputId ?? GenerateId("key:2", 1, UniqueIdFormat.HtmlId, null);
var submitButtonIdFinal = submitButtonId ?? GenerateId("key:3", 1, UniqueIdFormat.Guid, null);
return OriginalClass.CreateFormWithMultipleIds(formIdFinal, nameInputIdFinal, emailInputIdFinal, submitButtonIdFinal);
}
๐งช Testing
The project includes a comprehensive test suite covering:
- Basic functionality - Core ID generation and validation
- Multiple parameter support - Methods with multiple
[UniqueId]parameters - Format compliance - Each format meets its specification
- Edge cases - Error conditions and unusual scenarios
- Performance - Concurrency and load testing
- Integration - Real-world usage patterns with actual
[UniqueId]attributes
Run tests with:
dotnet test
๐ง Requirements
- .NET 10.0 or later (for interceptor support)
- C# preview (interceptors are preview)
- EnablePreviewFeatures and InterceptorsNamespaces enabled in your project
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Praefixum</InterceptorsNamespaces>
</PropertyGroup>
๐ค Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Development Setup
- Clone the repository
- Run
dotnet restore - Run
dotnet buildto build all projects - Run
dotnet testto execute the test suite
๐ Project Structure
Praefixum/
โโโ Praefixum/ # Main source generator project
โ โโโ UniqueIdGenerator.cs # Core source generator logic
โ โโโ UniqueIdAttribute.cs # Attribute definitions
โโโ Praefixum.Demo/ # Demo application
โ โโโ Program.cs # Console demo
โ โโโ Html.cs # HTML generation examples
โโโ Praefixum.Tests/ # Comprehensive test suite
โ โโโ UniqueIdGeneratorBasicTests.cs
โ โโโ UniqueIdGeneratorEdgeCaseTests.cs
โ โโโ UniqueIdFormatTests.cs
โ โโโ UniqueIdGeneratorPerformanceTests.cs
โ โโโ TestHelpers.cs
โโโ docs/ # Documentation
๐ Performance
- No runtime ID generation - IDs are compile-time literals in generated code
- Fast compilation - Minimal impact on build time
- Memory efficient - No runtime allocations for ID generation
- Thread-safe - Generated constants are inherently thread-safe
๐ Troubleshooting
Common Issues
Q: IDs are not being generated A: Ensure you're using .NET 10 and have enabled preview features and interceptors in your project.
Q: Duplicate ID errors A: This indicates the same call site is generating multiple IDs. Check your code structure.
Q: Build errors with interceptors
A: Verify your project targets .NET 10, LangVersion is preview, and preview features are enabled.
๐ License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
๐ Acknowledgments
- Built with Roslyn source generators
- Uses .NET 10 preview interceptor feature
- Inspired by compile-time code generation patterns
Made with โค๏ธ for the .NET community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Praefixum:
| Package | Downloads |
|---|---|
|
Picea.Abies
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.1 | 6,434 | 2/25/2026 |
| 2.0.0 | 112 | 2/18/2026 |
| 1.2.1-tags-v1-2-0.1 | 1,993 | 1/22/2026 |
| 1.1.9-tags-v1-1-8.1 | 148 | 1/21/2026 |
| 1.1.8-tags-v1-1-7.1 | 76 | 1/21/2026 |
| 1.1.6-tags-v1-1-5.1 | 189 | 6/23/2025 |
| 1.1.5-tags-v1-1-4.1 | 349 | 6/6/2025 |
| 1.1.4-tags-v1-1-3.2 | 169 | 6/5/2025 |
| 1.1.3-tags-v1-1-2.1 | 174 | 6/4/2025 |
| 1.1.2-tags-v1-1-1.1 | 173 | 6/4/2025 |
| 1.1.1-tags-v1-1-0.1 | 178 | 6/4/2025 |
| 1.0.19-tags-v1-0-18.1 | 174 | 5/27/2025 |
| 1.0.12-tags-v1-0-11.1 | 188 | 5/26/2025 |
| 1.0.11-tags-v1-0-10.1 | 133 | 5/23/2025 |
v2.0.1 โ Bugfix: emit correct C# literals for bool, char, float, double, decimal, long, ulong, and enum default parameter values in generated interceptors (#6).