Skip to content

Fix value type builder selection when a nullable sibling factory is present#4289

Merged
jeremydmiller merged 1 commit intoJasperFx:masterfrom
lucasbagrt:fix-4288-value-type-with-nullable-factory
Apr 26, 2026
Merged

Fix value type builder selection when a nullable sibling factory is present#4289
jeremydmiller merged 1 commit intoJasperFx:masterfrom
lucasbagrt:fix-4288-value-type-with-nullable-factory

Conversation

@lucasbagrt
Copy link
Copy Markdown
Contributor

@lucasbagrt lucasbagrt commented Apr 25, 2026

Suggestion on a fix for issue #4288

Why

RegisterValueType selected the static builder method by parameter signature alone (FirstOrDefault over public
static methods with one parameter matching the wrapped value type). When a Vogen value object had a nullable sibling
factory — e.g. static T? FromNullable(string?) alongside static T From(string)FirstOrDefault could pick the
nullable one. That builder's ReturnType is Nullable<T>, which then blew up inside ValueTypeInfo.CreateWrapper,
which assumes the builder returns T itself. The symptom reported in #4288 was a crash when generating DDL for any
computed index over the value type.

Changes

  • src/Marten/StoreOptions.Identity.csRegisterValueType now collects every candidate with the correct parameter
    signature and prefers the one whose ReturnType == type, falling back to the first candidate. Preserves prior
    behaviour for value types that expose only a single matching builder.
  • src/ValueTypeTests/Bugs/Bug_4288_value_type_with_nullable_factory.cs — regression test covering (1) DDL generation
    for a computed index over the value type and (2) round-trip + query using Bug4288Value, which exposes
    FromNullable.
  • src/ValueTypeTests/registration.cs — new unit test picks_builder_whose_return_type_matches_value_type that pins
    the selection rule, plus a SpecialValueWithNullableSibling fixture (with From and FromNullable side by side).

Verification

  • dotnet build src/Marten/Marten.csproj — succeeds.
  • dotnet test src/ValueTypeTests/ValueTypeTests.csproj
    registration.picks_builder_whose_return_type_matches_value_type (pure unit test, no Postgres dependency) passes;
    Bug_4288_value_type_with_nullable_factory
    (can_generate_ddl_for_index_over_value_type_with_nullable_sibling_factory and
    can_round_trip_and_query_value_type_with_nullable_sibling_factory) passes against a local Postgres; the existing
    registration suite stays green.
  • Behaviour is unchanged for value types with only a single matching builder — the FirstOrDefault() fallback returns
    the same method the old code used to pick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants