Philiprehberger.ValueOf
0.2.0
dotnet add package Philiprehberger.ValueOf --version 0.2.0
NuGet\Install-Package Philiprehberger.ValueOf -Version 0.2.0
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="Philiprehberger.ValueOf" Version="0.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Philiprehberger.ValueOf" Version="0.2.0" />
<PackageReference Include="Philiprehberger.ValueOf" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Philiprehberger.ValueOf --version 0.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Philiprehberger.ValueOf, 0.2.0"
#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.
#:package Philiprehberger.ValueOf@0.2.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Philiprehberger.ValueOf&version=0.2.0
#tool nuget:?package=Philiprehberger.ValueOf&version=0.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Philiprehberger.ValueOf
Strongly-typed value objects with built-in validation and JSON support — eliminate primitive obsession.
Installation
dotnet add package Philiprehberger.ValueOf
Usage
Define a custom value object
using Philiprehberger.ValueOf;
public class EmailAddress : ValueOf<string, EmailAddress>
{
protected override void Validate()
{
if (string.IsNullOrWhiteSpace(Value) || !Value.Contains('@'))
throw new ValueOfValidationException(typeof(EmailAddress), "Invalid email address.");
}
}
Create and use instances
var email = EmailAddress.From("user@example.com");
string raw = email; // implicit conversion to string
var copy = (EmailAddress)"a@b.com"; // explicit conversion from string
Console.WriteLine(email); // "user@example.com"
Console.WriteLine(email == copy); // False
Built-in types
var name = NonEmptyString.From("Alice");
var count = PositiveInt.From(42);
var rate = Percentage.From(99.5m);
// Validation throws on invalid values
NonEmptyString.From(""); // throws ValueOfValidationException
PositiveInt.From(-1); // throws ValueOfValidationException
Percentage.From(101m); // throws ValueOfValidationException
Non-throwing creation with TryFrom
using Philiprehberger.ValueOf;
if (PositiveInt.TryFrom(userInput, out var positive))
{
Console.WriteLine($"Got {positive!.Value}");
}
else
{
Console.WriteLine("Invalid value, no exception raised.");
}
Additional built-in types
using Philiprehberger.ValueOf;
var clicks = NonNegativeInt.From(0);
var ratio = UnitInterval.From(0.75m); // 0 ≤ value ≤ 1
var name = NonEmptyTrimmedString.From(" hi "); // stores "hi"
JSON serialization
using System.Text.Json;
var options = new JsonSerializerOptions();
options.Converters.Add(new ValueOfJsonConverterFactory());
var json = JsonSerializer.Serialize(email, options); // "\"user@example.com\""
var back = JsonSerializer.Deserialize<EmailAddress>(json, options);
API
ValueOf<TValue, TSelf>
| Member | Description |
|---|---|
Value |
The underlying primitive value |
From(TValue) |
Creates a validated instance (throws on null/invalid) |
TryFrom(TValue, out TSelf?) |
Non-throwing variant; returns false on validation failure |
Validate() |
Override to add custom validation logic |
Equals(TSelf) |
Value-based equality |
CompareTo(TSelf) |
Value-based comparison |
ToString() |
Returns string representation of the value |
operator == / != |
Equality operators |
implicit operator TValue |
Unwraps to the underlying value |
explicit operator ValueOf |
Wraps a primitive into the value object |
ValueOfJsonConverterFactory
| Member | Description |
|---|---|
CanConvert(Type) |
Returns true for any ValueOf<,> derived type |
CreateConverter(Type, JsonSerializerOptions) |
Creates a converter that reads/writes the underlying value |
ValueOfValidationException
| Member | Description |
|---|---|
ValueObjectType |
The type that failed validation |
Message |
Formatted as "{TypeName}: {message}" |
Built-in Types
| Type | Wraps | Validation |
|---|---|---|
NonEmptyString |
string |
Not null or empty |
NonEmptyTrimmedString |
string |
Not null/empty after trimming whitespace; stored trimmed |
PositiveInt |
int |
Greater than 0 |
NonNegativeInt |
int |
Greater than or equal to 0 |
Percentage |
decimal |
Between 0 and 100 inclusive |
UnitInterval |
decimal |
Between 0 and 1 inclusive |
ValueOfAttribute
Marker attribute for decorating value object types. Reserved for future source generator support.
Development
dotnet build src/Philiprehberger.ValueOf.csproj --configuration Release
Support
If you find this project useful:
License
| Product | Versions 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. 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.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.