Qowaiv.CodeGeneration.SingleValueObjects 1.1.3

dotnet add package Qowaiv.CodeGeneration.SingleValueObjects --version 1.1.3
                    
NuGet\Install-Package Qowaiv.CodeGeneration.SingleValueObjects -Version 1.1.3
                    
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="Qowaiv.CodeGeneration.SingleValueObjects" Version="1.1.3">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Qowaiv.CodeGeneration.SingleValueObjects" Version="1.1.3" />
                    
Directory.Packages.props
<PackageReference Include="Qowaiv.CodeGeneration.SingleValueObjects">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
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 Qowaiv.CodeGeneration.SingleValueObjects --version 1.1.3
                    
#r "nuget: Qowaiv.CodeGeneration.SingleValueObjects, 1.1.3"
                    
#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.
#addin nuget:?package=Qowaiv.CodeGeneration.SingleValueObjects&version=1.1.3
                    
Install Qowaiv.CodeGeneration.SingleValueObjects as a Cake Addin
#tool nuget:?package=Qowaiv.CodeGeneration.SingleValueObjects&version=1.1.3
                    
Install Qowaiv.CodeGeneration.SingleValueObjects as a Cake Tool

Custom Single Value Objects

Generated ID's

Primitive Obsession is a common issue when dealing with identifiers. It is quite common to provide two or even more identifiers (of different identities) to a method, which can lead to nasty bugs.

To overcome this, strongly-typed identifiers can save the day: a specific type per identifier per identity. With code generation, creating those ID's becomes a trivial task.

[Id<GuidBehavior, Guid>] // Also StringIdBehavior, Int32Behavior, Int64Behavior and UuidBehavior are available
public readonly partial struct DocumentId { }

customization

If needed, the behavior can be tweaked extening the provided behavior. Behavior that can be overridden:

  • TypeConvertion
  • Parsing
  • IdGeneration
  • Formatting
  • Sorting
  • Serialization (JSON and XML)

This can be done as follows:

[Id<Behavior, string>]
public readonly partial struct ProjectId
{
    private sealed class Behavior : StringIdBehavior
    {
        public override string NextId()
            => $"{Clock.Today().Year}-{Uuid.NextUid()[..8]}";
    }
}

Generated SVO's

Creating SVO's for the scope of (just) a project, might feel like a burden that is not worth the effort. To reduce the burden, this package comes with a code generator:

[Svo<CustomBehavior>]
public partial readonly struct CustomSvo
{
    private sealed class CustomBehavior : SvoBehavior { /* .. */ }
}

Just having this definition might prevent some primitive obsession, but with implementing some custom behavior, we can achieve some nice results.

Validation

Ensuring the validness of a SVO is key. The following mechanisms are provided:

Setting the minimum and/or maximum length

By simply setting the MinLength and/or the MaxLength strings exceeding these constrains are rejected:

private sealed class CustomBehavior : SvoBehavior
{
    public override int MinLength => 3;
    public override int MaxLength => 9;
}
A regular expression pattern

If defined, the Regex pattern can act as a second line of defense. As in the following example, where we ensure that all characters that make up the SVO are alphanumeric:

private sealed class CustomBehavior : SvoBehavior
{
    public override Regex Pattern => new("^([A-Z][0-9])+$");
}
Overriding the validation method

For more complex scenarios, the first options provided might not be sufficient. Therefore, is also possible to override IsValid():

private sealed class CustomBehavior : SvoBehavior
{
    public override bool IsValid(string str, IFormatProvider? formatProvider, out string validated)
    {
        if (long.TryParse(str, out var number))
        {
            validated = number.ToString("000");
            return true;
        }
        else
        {
            validated = default;
            return false;
        }
    }
}
Normalizing input

Before the input string is validated, the NormalizeInput() method is called. By default the input is trimmed, but if preferred, extra measures can be taken:

private sealed class CustomBehavior : SvoBehavior
{
    public override string NormalizeInput(string str, IFormatProvider formatProvider) 
        => str?.Replace("-", "").ToUpperInvariant()
        ?? string.Empty;
}

Formatting

By default the formatting is simple: string.Empty for the empty state, "?" for the unknown state, and the internally stored string for the rest. The empty state behavior is not overridable, the other two are:

private sealed class CustomBehavior : SvoBehavior
{
    public override string FormatUnknown(string? format, IFormatProvider? formatProvider) 
        => "Unknown";

    public override string Format(string str, string? format, IFormatProvider? formatProvider)
        => format == "l"
        ? str.ToLower()
        : str;
}
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .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.

Version Downloads Last updated
1.1.3 153 6/5/2025
1.1.2 188 6/2/2025
1.1.1 1,310 5/13/2025
1.1.0 209 5/12/2025
1.0.2 217 4/23/2025
1.0.1 149 4/23/2025
1.0.0 219 4/23/2025

v1.1.3
- Use Microsoft.CodeAnalysis.CSharp v4.11.0 (.NET 8.0).
v1.1.2
- ID m_Value's raw type with global:: namespace prefix.
- ID's implement INext<TSvo>.
- ID's can be generated in the global namespace.
- ID ToString() supports custom formatters and string.Empty for default value.
v1.1.1
- Do not generate Create and TryCreate for string based ID's.
v1.1.0
- Generated custom ID's.
v1.0.2
- Fixes for Generation before .NET 6.0.
v1.0.1
- Generate JSON Converter only for .NET 6.0 and higher.
v1.0.0
- Generate custom SVO's.