RSCG – StronglyTypedUid

name StronglyTypedUid
nuget https://www.nuget.org/packages/StronglyTypedUid/
link https://github.com/vicosanz/StronglyTypedUid
author Victor Sánchez

Transforming a record into a GUID

 

This is how you can use StronglyTypedUid .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="StronglyTypedUid" Version="1.0.1" />
    <PackageReference Include="StronglyTypedUid.Common" Version="1.0.1" />
    <PackageReference Include="StronglyTypedUid.Generator" Version="1.0.1" />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using RecordToGuid;

PersonId personId = PersonId.Empty;
Console.WriteLine(personId);
personId = PersonId.NewPersonId();
Console.WriteLine(personId);




using StronglyTypedUid;

namespace RecordToGuid;
[StronglyTypedUid]
public readonly partial record struct PersonId
{
}


 

The code that is generated is

using System;
using System.ComponentModel;
using System.Globalization;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Buffers;

using StronglyTypedUid;

#nullable enable

namespace RecordToGuid;

[TypeConverter(typeof(PersonIdTypeConverter))]
[System.Text.Json.Serialization.JsonConverter(typeof(PersonIdJsonConverter))]
public readonly partial record struct PersonId(Guid Value) : IStronglyTypedUid
{
    public static PersonId Empty => new(Guid.Empty);

    public static PersonId NewPersonId() => new(Guid.NewGuid());

    public static implicit operator PersonId(Guid value) => new(value);

    public static explicit operator Guid(PersonId value) => value.Value;

    public bool IsEmpty => Value == Guid.Empty;

    public override string ToString() => Value.ToString();

    public static PersonId Parse(string text) => new PersonId(Guid.Parse(text));

    public static bool TryParse(string text, out PersonId result)
    {
        try
        {
            if (Guid.TryParse(text, out Guid uid))
            {
                result = uid;
                return true;
            }
        }
        catch (Exception)
        {
        }
        result = default;
        return false;
    }
}

public class PersonIdTypeConverter : TypeConverter
{
    private static readonly Type StringType = typeof(string);
    private static readonly Type UidType = typeof(Guid);

    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) => 
        sourceType == StringType || sourceType == UidType || base.CanConvertFrom(context, sourceType);

    public override object? ConvertFrom(ITypeDescriptorContext? context,
        CultureInfo? culture, object value) => value switch
        {
            Guid g => new PersonId(g),
            string stringValue => PersonId.Parse(stringValue),
            _ => base.ConvertFrom(context, culture, value),
        };

    public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) =>
        destinationType == StringType || destinationType == UidType || base.CanConvertTo(context, destinationType);

    public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
    {
        if (value is PersonId result)
        {
            if (destinationType == StringType)
            {
                return result.ToString();
            }
            if (destinationType == UidType)
            {
                return (Guid)result;
            }
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

public class PersonIdJsonConverter : JsonConverter<PersonId>
{
    public override PersonId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        try
        {
            if (reader.TokenType != JsonTokenType.String) throw new JsonException("Expected string");
            return new PersonId(new Guid(reader.GetString()));
        }
        catch (IndexOutOfRangeException e)
        {
            throw new JsonException("PersonId invalid: length must be 36", e);
        }
        catch (OverflowException e)
        {
            throw new JsonException("PersonId invalid: invalid character", e);
        }
    }
    public override void Write(Utf8JsonWriter writer, PersonId value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}


Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/StronglyTypedUid