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 (2)
Showing the top 2 NuGet packages that depend on Praefixum:
| Package | Downloads |
|---|---|
|
Picea.Abies
Package Description |
|
|
Picea.Abies.Native
Native control vocabulary and platform-neutral patch interpreter for the Abies MVU framework. Describes native UI (StackPanel, TextBlock, Button, ...) as Abies virtual DOM elements and interprets the resulting patch stream against any INativeBackend implementation. No UI framework dependencies. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.1 | 8,090 | 2/25/2026 |
| 2.0.0 | 130 | 2/18/2026 |
| 1.2.1-tags-v1-2-0.1 | 2,009 | 1/22/2026 |
| 1.1.9-tags-v1-1-8.1 | 161 | 1/21/2026 |
| 1.1.8-tags-v1-1-7.1 | 90 | 1/21/2026 |
| 1.1.6-tags-v1-1-5.1 | 202 | 6/23/2025 |
| 1.1.5-tags-v1-1-4.1 | 362 | 6/6/2025 |
| 1.1.4-tags-v1-1-3.2 | 182 | 6/5/2025 |
| 1.1.3-tags-v1-1-2.1 | 192 | 6/4/2025 |
| 1.1.2-tags-v1-1-1.1 | 183 | 6/4/2025 |
| 1.1.1-tags-v1-1-0.1 | 190 | 6/4/2025 |
| 1.0.19-tags-v1-0-18.1 | 186 | 5/27/2025 |
| 1.0.12-tags-v1-0-11.1 | 198 | 5/26/2025 |
| 1.0.11-tags-v1-0-10.1 | 146 | 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).