Context
The current PR (#14) ships NonEmptyStringValueConverter and the ModelConfigurationBuilder.UseStrongTypes() extension in the StrongTypes.Api project, because we didn't want to add an EF Core dependency to the core StrongTypes library.
That keeps the core library EF-free, but the downside is that library consumers (anyone pulling the Kalicz.StrongTypes NuGet package) can't reach the converter — they'd have to copy the class into their own codebase to persist NonEmptyString with EF Core.
Proposal
Add a new project src/StrongTypes.EFCore/ shipping as a separate NuGet package Kalicz.StrongTypes.EFCore that:
- Depends on
Kalicz.StrongTypes + Microsoft.EntityFrameworkCore (relational, to allow HaveConversion).
- Contains
NonEmptyStringValueConverter (moved from StrongTypes.Api/Infrastructure/).
- Contains
ModelConfigurationBuilder.UseStrongTypes() (moved from StrongTypes.Api/Infrastructure/).
- Grows one line per new strong type as
PositiveInt, NonNegativeDecimal, etc. land.
StrongTypes.Api then takes a ProjectReference to StrongTypes.EFCore instead of hosting the converter inline.
Why not now
Out of scope for the PR that introduced the converter — that PR is about wiring NonEmptyString through the integration-test harness. Splitting the package is its own decision (naming, targeting, versioning) and deserves its own commit history.
Done when
Discoverability (what users see in their IDE)
VS and Rider already ship an "unresolved symbol → install NuGet package" code fix that queries nuget.org's search index. That means once this package is published, a user who types UseStrongTypes() or NonEmptyStringValueConverter without a reference will be offered the install in their lightbulb menu — no extra work on our side. API shape (extension on ModelConfigurationBuilder vs. DbContextOptionsBuilder) doesn't change this; both are picked up identically.
To make that path work reliably:
- Publish to nuget.org under
Kalicz.StrongTypes.EFCore (match the existing Kalicz.StrongTypes prefix so users find it by typing the known prefix).
<PackageTags> on the csproj should include EntityFrameworkCore, EFCore, ValueConverter, StrongTypes, NonEmptyString so search ranks the package when users grep for those concepts.
<Description> should mention "EF Core value converters for StrongTypes" verbatim — this is what surfaces in the package browser and in the "Install package X" tooltip.
<PackageReadmeFile> with a short code sample showing the UseStrongTypes() one-liner — the readme renders both on nuget.org and in the IDE's package details pane.
What this does not cover
The install-on-unresolved-symbol fix only fires once the user reaches for a type or extension from the package. It cannot proactively warn "you declared a NonEmptyString EF-mapped column and haven't installed the converter yet." That would require a Roslyn analyzer shipped inside the core Kalicz.StrongTypes package — tracked separately in #17.
Context
The current PR (#14) ships
NonEmptyStringValueConverterand theModelConfigurationBuilder.UseStrongTypes()extension in theStrongTypes.Apiproject, because we didn't want to add an EF Core dependency to the coreStrongTypeslibrary.That keeps the core library EF-free, but the downside is that library consumers (anyone pulling the
Kalicz.StrongTypesNuGet package) can't reach the converter — they'd have to copy the class into their own codebase to persistNonEmptyStringwith EF Core.Proposal
Add a new project
src/StrongTypes.EFCore/shipping as a separate NuGet packageKalicz.StrongTypes.EFCorethat:Kalicz.StrongTypes+Microsoft.EntityFrameworkCore(relational, to allowHaveConversion).NonEmptyStringValueConverter(moved fromStrongTypes.Api/Infrastructure/).ModelConfigurationBuilder.UseStrongTypes()(moved fromStrongTypes.Api/Infrastructure/).PositiveInt,NonNegativeDecimal, etc. land.StrongTypes.Apithen takes aProjectReferencetoStrongTypes.EFCoreinstead of hosting the converter inline.Why not now
Out of scope for the PR that introduced the converter — that PR is about wiring
NonEmptyStringthrough the integration-test harness. Splitting the package is its own decision (naming, targeting, versioning) and deserves its own commit history.Done when
StrongTypes.EFCoreproject exists, packs asKalicz.StrongTypes.EFCore.NonEmptyStringValueConverter+UseStrongTypes()live there.StrongTypes.Apireferences the new project; integration tests still pass.StrongTypesproject has no EF Core dependency.Discoverability (what users see in their IDE)
VS and Rider already ship an "unresolved symbol → install NuGet package" code fix that queries nuget.org's search index. That means once this package is published, a user who types
UseStrongTypes()orNonEmptyStringValueConverterwithout a reference will be offered the install in their lightbulb menu — no extra work on our side. API shape (extension onModelConfigurationBuildervs.DbContextOptionsBuilder) doesn't change this; both are picked up identically.To make that path work reliably:
Kalicz.StrongTypes.EFCore(match the existingKalicz.StrongTypesprefix so users find it by typing the known prefix).<PackageTags>on the csproj should includeEntityFrameworkCore,EFCore,ValueConverter,StrongTypes,NonEmptyStringso search ranks the package when users grep for those concepts.<Description>should mention "EF Core value converters for StrongTypes" verbatim — this is what surfaces in the package browser and in the "Install package X" tooltip.<PackageReadmeFile>with a short code sample showing theUseStrongTypes()one-liner — the readme renders both on nuget.org and in the IDE's package details pane.What this does not cover
The install-on-unresolved-symbol fix only fires once the user reaches for a type or extension from the package. It cannot proactively warn "you declared a
NonEmptyStringEF-mapped column and haven't installed the converter yet." That would require a Roslyn analyzer shipped inside the coreKalicz.StrongTypespackage — tracked separately in #17.