Demarbit.StrongIds
1.0.1
dotnet add package Demarbit.StrongIds --version 1.0.1
NuGet\Install-Package Demarbit.StrongIds -Version 1.0.1
<PackageReference Include="Demarbit.StrongIds" Version="1.0.1" />
<PackageVersion Include="Demarbit.StrongIds" Version="1.0.1" />
<PackageReference Include="Demarbit.StrongIds" />
paket add Demarbit.StrongIds --version 1.0.1
#r "nuget: Demarbit.StrongIds, 1.0.1"
#:package Demarbit.StrongIds@1.0.1
#addin nuget:?package=Demarbit.StrongIds&version=1.0.1
#tool nuget:?package=Demarbit.StrongIds&version=1.0.1
Demarbit.StrongIds
Strongly-typed IDs for .NET — eliminate primitive obsession with source-generated value types that include equality, comparison, parsing, JSON serialization, and type conversion out of the box.
Installation
dotnet add package Demarbit.StrongIds
The source generator is bundled — no additional packages or configuration needed.
What's Included
[StrongId] attribute — decorate a partial struct and the source generator produces a complete value type with equality, comparison, parsing, ToString(), and explicit/implicit conversions.
Backing types — Guid (default), Int, Long, and String. Choose the one that matches your persistence layer.
JSON serialization — a JsonConverter<T> is generated for each ID, so System.Text.Json serialization works without any configuration.
Type conversion — a TypeConverter is generated for ASP.NET Core model binding, route parameters, and query strings.
Quick Start
Define a Strongly-Typed ID
using Demarbit.StrongIds;
[StrongId]
public partial struct OrderId { }
That's it. The generator produces a readonly partial struct with a Guid backing type. You get:
OrderId.New()— creates a new ID with a randomGuidOrderId.From(guid)— wraps an existingGuidOrderId.Empty— the default/empty valueOrderId.Parse(string)andOrderId.TryParse(string, out OrderId)—IParsable<T>support- Full
IEquatable<OrderId>andIComparable<OrderId>implementations ==,!=operators- Implicit conversion to
Guid, explicit conversion fromGuid - Built-in
JsonConverterandTypeConverter
Choosing a Backing Type
[StrongId(BackingType.Guid)] // default
public partial struct OrderId { }
[StrongId(BackingType.Int)]
public partial struct LineNumber { }
[StrongId(BackingType.Long)]
public partial struct EventSequence { }
[StrongId(BackingType.String)]
public partial struct Slug { }
Using with Entities
Strong IDs pair naturally with Demarbit.Shared.Domain generic entities:
[StrongId]
public partial struct ProductId { }
public class Product : AggregateRoot<ProductId>
{
public string Name { get; private set; }
public Product(ProductId id, string name) : base(id)
{
Name = Guard.Against.NullOrWhiteSpace(name, nameof(name));
}
}
// Usage
var id = ProductId.New();
var product = new Product(id, "Widget");
API Controllers
The generated TypeConverter means ASP.NET Core binds route parameters automatically:
[HttpGet("{id}")]
public async Task<IActionResult> Get(OrderId id)
{
// id is parsed from the route string — no manual conversion needed
}
JSON Serialization
Works out of the box with System.Text.Json:
var order = new { Id = OrderId.New(), Name = "Test" };
var json = JsonSerializer.Serialize(order);
// {"Id":"d4f5a1b2-...","Name":"Test"}
Design Principles
This package follows a few deliberate constraints:
- Zero runtime dependencies — the attribute library has no dependencies. The source generator runs at compile time only and does not ship with your application.
- Compile-time generation — no reflection, no runtime code generation. The generated code is plain C# that you can inspect in your IDE.
- Small surface area — one attribute, one enum, four backing types. Everything else is generated.
- Framework integration —
IEquatable<T>,IComparable<T>,IParsable<T>,JsonConverter<T>, andTypeConverterare implemented so strong IDs work everywhere primitive types do.
Architecture Fit
This package complements the other Demarbit shared libraries:
Demarbit.StrongIds ← this package (zero runtime deps)
Demarbit.Shared.Domain ← EntityBase<TId> accepts any IEquatable<TId>
Demarbit.Shared.Application ← CQRS commands/queries use strong IDs as parameters
Demarbit.Shared.Infrastructure ← EF Core value converters for strong IDs
Each package can be used independently. A project using strong IDs without the shared domain library works fine — the generated structs implement IEquatable<T> which satisfies any generic constraint.
License
| 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
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.