Getting started
editInstall the package
Add the Meziantou.Framework.StronglyTypedId package to your project:
dotnet package add Meziantou.Framework.StronglyTypedIdThe package contains the source generator and the attributes. When the project enables implicit usings (<ImplicitUsings>enable</ImplicitUsings>), the package also adds global using Meziantou.Framework.Annotations;; otherwise, add the using directive yourself.
The examples of this documentation omit the using directives. They check their results with assertions such as Assert.Equal, which show what each call returns.
Declare an ID
Add [StronglyTypedId<T>] to a partial struct, where T is the type of the value:
[StronglyTypedId<int>]
public partial struct ProjectId { }The type must be partial, because the generator adds members to it. The body stays empty: everything else is generated when the project builds.
Use it
var id = ProjectId.FromInt32(42);
Assert.Equal(42, id.Value);
Assert.Equal("42", id.ValueAsString);
Assert.Equal("ProjectId { Value = 42 }", id.ToString());
// Two ids are equal when their values are equal
Assert.Equal(ProjectId.FromInt32(42), id);
Assert.Equal(id, ProjectId.Parse("42"));
Assert.True(ProjectId.TryParse("42", out var parsed));
Assert.Equal(id, parsed);
Assert.False(ProjectId.TryParse("abc", out _));FromInt32creates an ID. The name of the method follows the underlying type:FromGuid,FromString,FromInt64... The constructor is private.Valueis the underlying value, and ValueAsString the value formatted with the invariant culture.ToString()shows the type and the value, like a record. You can get the bare value instead: see Options.- Equality compares the values, and
ParseandTryParseread the string representation.
Serialize it
An ID is serialized as its value, so an ID created from 42 becomes 42 in JSON:
var userId = UserId.FromInt32(42);
var json = System.Text.Json.JsonSerializer.Serialize(userId);
Assert.Equal("42", json);The System.Text.Json converter is generated for every ID, and the Newtonsoft.Json and MongoDB converters when the project references these libraries. See Integrations.
Next steps
- Declaring IDs: structs, classes and records, and the attribute for older C# versions.
- Underlying types: the types an ID can wrap.
- Validation and custom members: reject invalid values.