Skip to content

Releases: PawelGerr/Thinktecture.Runtime.Extensions

10.2.0

10 Apr 11:03
68b8615

Choose a tag to compare

  • Support for generic ad hoc unions, smart enums and keyed value objects
  • Ad hoc unions get factories for all member if at least 1 requires a factory
  • Source generators add GeneratedCodeAttribute, DebuggerNonUserCodeAttribute and EditorBrowsable where applicable
  • Added null check for generics without struct constraint

10.1.2

26 Mar 17:01
3c1061e

Choose a tag to compare

  • Fix code generation for operators that have no corresponding static abstract interface member

10.1.1

24 Mar 21:28
57262b1

Choose a tag to compare

  • Fix JSON serialization of ComplexValueObjects with nullable Smart Enum or keyed Value Object properties throwing ArgumentNullException when the property value is null (#19).

10.1.0

12 Mar 19:27
2a85304

Choose a tag to compare

  • New IDE Refactoring: Switch/Map Argument Completion -- a light-bulb action that auto-generates arguments for Switch, Map, SwitchPartially, and MapPartially method calls
  • New Analyzer Diagnostic: TTRESG1001 -- detects non-static lambdas in Switch/Map calls and suggests static lambdas or the state overload to avoid allocations
  • Bug Fix: TTRESG104 no longer fires on interface properties
  • Lifted restriction TTRESG052 (Types are now allowed inside generic types)
  • Improve error message in ad hoc unions' methods "AsFoo"

10.1.0-beta03

09 Mar 11:44
6539101

Choose a tag to compare

10.1.0-beta03 Pre-release
Pre-release
  • Lifted restriction TTRESG052 (Types are now allowed inside generic types)

10.1.0-beta02

02 Mar 10:28
d8beaa6

Choose a tag to compare

10.1.0-beta02 Pre-release
Pre-release
  • Installation of package Thinktecture.Runtime.Extensions.Refactorings is not necessary for the new IDE Refactoring (Switch/Map Argument Completion) - Thinktecture.Runtime.Extensions.Refactorings is now a dependency of Thinktecture.Runtime.Extensions

10.1.0-beta01

01 Mar 22:28
7e8d22d

Choose a tag to compare

10.1.0-beta01 Pre-release
Pre-release
  • New IDE Refactoring: Switch/Map Argument Completion -- a light-bulb action that auto-generates arguments for Switch, Map, SwitchPartially, and MapPartially method calls (needs package Thinktecture.Runtime.Extensions.Refactorings
  • New Analyzer Diagnostic: TTRESG1001 -- detects non-static lambdas in Switch/Map calls and suggests static lambdas or the state overload to avoid allocations
  • Bug Fix: TTRESG104 no longer fires on interface properties

10.0.0

12 Feb 19:36
6be5b5e

Choose a tag to compare

Highlights

  • Generic Smart Enums and Keyed Value Objects -- the restriction against open generics has been lifted
  • Stateless Ad-Hoc Union Members -- union members that carry no instance, just a discriminator
  • Zero-Allocation JSON Deserialization -- span-based parsing for string-keyed Smart Enums (NET9+)
  • New EF Core Configuration API -- structured, type-safe configuration with built-in max length strategies
  • 5 new analyzer diagnostics (TTRESG060-062, TTRESG105-106) with a code fix for TTRESG105

Breaking Changes

For detailed migration instructions, see Migration from v9 to v10.

Framework Support

  • Dropped .NET 7 support -- minimum version is now .NET 8.0
  • Dropped Entity Framework Core 7 support -- minimum version is now EF Core 8.0
  • Minimum .NET SDK increased to 8.0.416

Removed Obsolete APIs

All types and members previously marked [Obsolete] have been deleted:

Removed Replacement
UseValueObjectValueConverter UseThinktectureValueConverters
AddValueObjectConverters AddThinktectureValueConverters
IEnum<TKey> ISmartEnum<TKey>
IEnum<TKey, T, TValidationError> ISmartEnum<TKey, T, TValidationError>
IValueObjectFactory<TValue> IObjectFactory<TValue>
IValueObjectFactory<T, TValue, TValidationError> IObjectFactory<T, TValue, TValidationError>
IComplexValueObject -
ValueObjectAccessModifier AccessModifier
TrimmingSmartEnumModelBinder -

Several obsolete attribute constructor overloads were also removed.

Entity Framework Core Configuration

The old callback-based UseThinktectureValueConverters API is deprecated. The new API uses a Configuration object with type-safe settings and built-in max length strategies:

// New API (v10)
.UseThinktectureValueConverters(new Configuration
{
   SmartEnums = new SmartEnumConfiguration
   {
      MaxLengthStrategy = DefaultSmartEnumMaxLengthStrategy.Instance
   },
   KeyedValueObjects = new KeyedValueObjectConfiguration
   {
      MaxLengthStrategy = new CustomKeyedValueObjectMaxLengthStrategy((type, keyType) =>
      {
         if (type == typeof(ProductName))
            return 200;

         return MaxLengthChange.None;
      })
   }
});

Discriminated Unions: Simplified Switch/Map Parameter Names

For Regular Unions nested inside another type, the union name is no longer included in the parameter name:

// v9
failure.Switch(failureNotFound: notFound => ..., failureUnauthorized: unauthorized => ...);

// v10
failure.Switch(notFound: notFound => ..., unauthorized: unauthorized => ...);

Swashbuckle Update

Updated Swashbuckle.AspNetCore.SwaggerGen dependency to 10.0.1.


New Features

Generic Smart Enums and Keyed Value Objects

The restriction preventing Smart Enums and Keyed Value Objects from being generic has been lifted. You can now define open generic types:

[SmartEnum<string>]
public sealed partial class MyEnum<T>
{
   public static readonly MyEnum<T> Item1 = new("Item1");
}

Stateless Ad-Hoc Union Members

Union members that are singletons or carry no meaningful state can be declared stateless. The union stores only the discriminator, not the instance:

[Union<Success, Failure>(T1IsStateless = true)]
public partial class Result;

When TXIsStateless = true, the union does not allocate storage for that member's instance. Prefer structs for stateless types.

Zero-Allocation JSON Deserialization

On NET9+, string-keyed Smart Enums automatically use span-based JSON deserialization, avoiding string allocations during JsonSerializer.Deserialize. This is enabled by default and can be opted out via:

[SmartEnum<string>(DisableSpanBasedJsonConversion = true)]
public sealed partial class ProductType;

For Keyed Value Objects, opt in via ObjectFactory<ReadOnlySpan<char>>:

[ValueObject<string>]
[ObjectFactory<ReadOnlySpan<char>>(UseForSerialization = SerializationFrameworks.SystemTextJson)]
public sealed partial class ProductName;

Extended ISpanParsable Support

On NET9+, generated types implement ISpanParsable<T> where applicable, enabling efficient parsing from ReadOnlySpan<char>.

Configurable Parameter Naming for Nested Regular Unions

The new NestedUnionParameterNameGeneration setting controls how parameter names are generated in Switch/Map for nested unions:

  • ShortName (default in v10) -- uses just the derived type name
  • FullName -- preserves the v9 behavior with the union name prefix

SwitchMapStateParameterName for Keyless Smart Enums

Keyless [SmartEnum] types now support the SwitchMapStateParameterName property to customize the state parameter name in generated Switch and Map methods.

New EF Core Configuration API

The new Configuration class provides:

  • Type-safe configuration for Smart Enums and Keyed Value Objects separately
  • Built-in max length strategies (DefaultSmartEnumMaxLengthStrategy automatically calculates from items)
  • Custom strategies via CustomKeyedValueObjectMaxLengthStrategy

See the Migration Guide for examples.


New Analyzer Diagnostics

ID Severity Description
TTRESG060 Error Smart Enums with ObjectFactoryAttribute<T> must not have HasCorrespondingConstructor set to true
TTRESG061 Error Type with ObjectFactoryAttribute<TValue> must implement a static Validate method
TTRESG062 Error Type with ObjectFactoryAttribute<TValue> must implement a ToValue method when used for serialization or Entity Framework
TTRESG105 Warning Comparison and equality operators settings mismatch (includes a code fix)
TTRESG106 Warning Inner type does not derive from union type

Bug Fixes

  • Fixed value tuple expansion in generated code
  • Fixed parameter naming for nested Regular Unions defined inside classes

Infrastructure

  • Migrated test framework from xunit v2 to xunit v3
  • Adopted C# 14 field keyword in runtime library code
  • Updated target frameworks to include .NET 10.0 alongside .NET 8.0 and .NET 9.0

10.0.0-beta03

13 Jan 11:14
15a8279

Choose a tag to compare

10.0.0-beta03 Pre-release
Pre-release
  • [BREAKING]: Name of the nested union is not used for building method argument names to make them shorter (in Switch/Map)

10.0.0-beta02

30 Nov 22:30
ade77f7

Choose a tag to compare

10.0.0-beta02 Pre-release
Pre-release
  • Better support for ISpanParsable
  • New EF Core configuration