StrictId 1.0.1

Suggested Alternatives

StrictId 1.1.0

Additional Details

This version of the package allows for implicit downcasts, which can result in loss of type information and type-unsafe comparisons. Upgrade to 1.1.0 or later for better type safety.

There is a newer version of this package available.
See the version list below for details.
dotnet add package StrictId --version 1.0.1                
NuGet\Install-Package StrictId -Version 1.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StrictId" Version="1.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add StrictId --version 1.0.1                
#r "nuget: StrictId, 1.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install StrictId as a Cake Addin
#addin nuget:?package=StrictId&version=1.0.1

// Install StrictId as a Cake Tool
#tool nuget:?package=StrictId&version=1.0.1                

StrictId

Strongly-typed, ergonomic, compatible, fun to use identifiers for your entities


What

public class Person {
    public Id<Person> Id { get; init; } // Strongly typed ID, with Ulid as the underlying type
    public Id<Dog> BestFriendId { get; set; } // No confusion about what ID we are looking for here
    public List<Id> Friends { get; set; } // Non-strict/non-generic version also included
}
  • Strongly-typed IDs for your entities, or anything else
  • Ulid as the underlying value, which can easily be converted to and from Guid, string, or byte arrays
  • Ergonomic, developer-friendly usage without ceremony, boilerplate, or annoyance
  • Built-in JSON conversion support for System.Text.Json
  • Full support for Entity Framework Core incl. value converters and value generators, with StrictId.EFCore
  • Full support for HotChocolate GraphQL incl. custom scalars for Id<T> and Id, with StrictId.HotChocolate
  • Tiny memory footprint and highly efficient

How

Recommended, but optional
In your global usings file, add the following to save yourself a few keystrokes:

global using Id = StrictId.Id;

Create

Id<Person>.NewId(); // Generate a new random ID
new Id<Person>("01HV9AF3QA4T121HCZ873M0BKK"); // Create from ULID string
new Id<Person>("018ED2A7-8EEA-2682-20C5-9F41C7402E73"); // Create from GUID string
new Id<Person>(Ulid.NewUlid()); // Create from ULID
new Id<Person>(Guid.NewGuid()); // Create from GUID
new Id<Person>(Id.NewId()); // Create from non-typed ID

Id<Person> id = Ulid.NewUlid(); // Convert implicitly from Ulid
Id<Person> id = Guid.NewGuid(); // Convert implicitly from Guid
var id = (Id<Person>)"01HV9AF3QA4T121HCZ873M0BKK"; // Cast from string
var id = (Id<Person>)Id.NewId(); // Cast from non-typed ID

Convert

var id = new Id<Person>("01HV9AF3QA4T121HCZ873M0BKK");

id.ToString(); // "01HV9AF3QA4T121HCZ873M0BKK"
id.ToUlid(); // Same as Ulid.Parse("01HV9AF3QA4T121HCZ873M0BKK");
id.ToGuid(); // Same as Guid.Parse("018ED2A7-8EEA-2682-20C5-9F41C7402E73");
id.ToByteArray(); // byte[]
id.IdValue // Id("018ED2A7-8EEA-2682-20C5-9F41C7402E73")

With Entity Framework Core

Install StrictId.EFCore via NuGet

In your DbContext:

using StrictId.EFCore;

public class MyDatabase (DbContextOptions<MyDatabase> options) : DbContext(options)
{
    protected override void ConfigureConventions (ModelConfigurationBuilder builder)
    {
        // ...
        
        builder.ConfigureStrictId();
    }
}

To generate values:

using StrictId.EFCore;

// ...

builder.Property(e => e.Id)
    .ValueGeneratedOnAdd()
    .HasStrictIdValueGenerator();

With Hot Chocolate GraphQL

Install StrictId.HotChocolate via NuGet

On the request executor builder, configure strict IDs:

builder.Services.AddGraphQLServer()
    // ...
    .AddStrictId();

Scalars will be created for each strict ID, named {Type}Id. For example, Id<Person> would become PersonId in the GraphQL schema.

Why

  • Using Guid or Ulid as the type for IDs can easily lead to mixing up method arguments and assignments
  • Other similar packages are cumbersome, non-compatible, and frankly annoying
  • Ulid as the underlying type provides neat benefits over simple Guids, as they are ordered, making databases less fragmented, and look nicer as strings

Acknowledgements

  • Ulid - Library for ULID in C#, used for much of the underlying functionality
  • StronglyTypedId - For doing this first, but in a much more convoluted, non-ergonomic, less compatible way

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

NuGet packages (2)

Showing the top 2 NuGet packages that depend on StrictId:

Package Downloads
StrictId.EFCore

Support for StrictId in Entity Framework Core.

StrictId.HotChocolate

Support for StrictId in Hot Chocolate.

GitHub repositories

This package is not used by any popular GitHub repositories.