Skip to content
Purview Dev logo

Value Objects

Stable

Source-generated scalar and complex value objects for .NET.

c-sharp csharp ddd domain-driven-design dotnet dto entity-framework immutable json roslyn scalar serialization single-case-union source-generator validation value-object value-objects zodsharp

The problem

F#-style single-case types for C#. Mark a partial struct or class with [Scalar] or [ValueObject] and an incremental source generator produces Create/Hydrate factories with normalization and validation, equality, comparison, implicit conversions, JSON converters, and contextual creation. Value objects serialize as their underlying value, map cleanly onto Entity Framework JSON columns, and can be validated with Purview.ZodSharp schemas.

From the repository

Source-generated scalar and complex value objects for .NET - F#-style single-case types with Create/Hydrate factories, normalization, validation, equality, JSON serialization, Entity Framework integration, and ZodSharp validation.

Why it became a project

Hand-writing the same factories, equality rules, conversions, serializers, and persistence integration for domain values made the pattern an obvious source-generation target.

Where it fits

Use it when

Your domain uses meaningful scalar or complex value types and you want their repetitive implementation generated from a small, explicit declaration.

It may not fit when

A primitive or record already expresses the concept clearly, or generated conversion and serialization behaviour would be more machinery than the domain needs.

Use cases

Concrete examples of what Value Objects does, and who each one is for.

Developer

A domain scalar without the boilerplate

You want a strong EmailAddress type with normalisation and validation, without hand-writing factories, equality, conversions, and a JSON converter.

csharp
[Scalar]
public readonly partial record struct EmailAddress
{
    public string Value { get; }

    static partial void OnNormalize(ref string value)
        => value = value?.Trim().ToLowerInvariant()!;
}

What you get: The generator adds Create, Hydrate, TryCreate, and Empty, plus equality, comparison, implicit conversions, and a JSON converter.

One declaration replaces the factory, equality, comparison, conversion, and serialization code you would otherwise maintain by hand.

Read the guide →
Developer

Map a value object onto an Entity Framework column

You use a value object in your domain and want it to persist transparently instead of writing converters at every mapping site.

csharp
var email = EmailAddress.Create("  [email protected]  ");
// email.Value == "[email protected]"

bool ok = EmailAddress.TryCreate("not-an-email", out _);
// ok == false

What you get: Value objects serialize as their underlying value and map onto Entity Framework JSON columns, with optional Purview.ZodSharp validation.

Persistence and serialization come from the generated type, so mapping code is not duplicated per entity.

Read the guide →

Packages

1 package

Purview.ValueObjectsnugetInstall ↓1.2.31.3.0-prerelease.22,043

Install

.NET CLI
dotnet add package Purview.ValueObjects

Agent skills

Value Objects authors agent skills for coding agents. They are installed explicitly with the skills CLI and are not part of any package.

Skills are installed explicitly with the skills CLI. Nothing ships them inside a NuGet package, and no build writes into your agent's directories: installation is a decision you make. Use whichever package manager you already have.

npm

Terminal window
npx skills add purview-dev/value-objects

bun

Terminal window
bunx skills add purview-dev/value-objects

pnpm

Terminal window
pnpm dlx skills add purview-dev/value-objects

yarn

Terminal window
yarn dlx skills add purview-dev/value-objects
  • Installs at project level by default. Add -g for a user-level install, or -a <agent> to target one agent.
  • To match the release you use, pin a commit or tag by appending #<ref> to any command above (for example npx skills add purview-dev/value-objects#<ref>).
  • The CLI records what it installed in skills-lock.json; restore it with the same runner:
Terminal window
npx skills experimental_install
  • purview-value-objects

    Use when modelling domain values with Purview.ValueObjects - scalar, complex or contextual value objects, typed identifiers, the Create/Hydrate split, OnNormalize/OnValidate hooks, built-in string normalization, assembly-level ValueObjectDefaults, JSON deserialization modes, or deciding where an invariant belongs.

    1 file
  • purview-value-objects-diagnostics

    Use when a Purview.ValueObjects build reports a VO1xxx diagnostic, when deciding whether to suppress one, or when adding a new analyzer rule to the value-objects source generator and its AnalyzerReleases tracking files.

    1 file
  • purview-value-objects-efcore

    Use when persisting Purview.ValueObjects with Entity Framework Core - ConfigureValueObjects, UseValueObjects, scalar-to-column conversion, complex-type versus JSON mapping, value objects as keys and foreign keys, query translation, generated key values, migrations, and the VO1009-VO1031 Entity Framework diagnostics.

    2 files
  • purview-value-objects-zodsharp

    Use when validating Purview.ValueObjects with Purview.ZodSharp - the [ZodSchema] integration that routes Create through a generated schema, ZodSchemaMode, the OnZodValidate refinement hook, custom rules and [ZodRule] attributes on scalars, schema-first Z.* validation, DTO validation, and mapping ZodException to ASP.NET Core Problem Details.

    2 files