Skip to content

FluentAssertions ships as a public dependency, propagating its licence to all consumers #56

Closed

Description

@poxet

Tharga.Cache 1.0.0 ships FluentAssertions as a public NuGet dependency, so every consumer of the package inherits it as a compile and runtime dependency.

Evidence

tharga.cache.nuspec (1.0.0):

<group targetFramework="net10.0">
  <dependency id="FluentAssertions" version="8.10.0" exclude="Build,Analyzers" />
  <dependency id="Microsoft.Extensions.Hosting.Abstractions" version="10.0.9" exclude="Build,Analyzers" />
</group>

Only Build and Analyzers are excluded, so compile and runtime assets flow through to consumers.

The dependency appears to be unintentional — the shipped assembly does not reference FluentAssertions at all. Scanning lib/net10.0/Tharga.Cache.dll for assembly-reference strings finds Microsoft.Extensions.Hosting.Abstractions but no FluentAssertions.

Why this matters

Licensing. FluentAssertions 8.x is under the Xceed Community License — free for open-source and non-commercial use, but requiring a paid licence for commercial use. Flowing it to consumers as a transitive runtime dependency silently propagates that obligation to anyone who installs Tharga.Cache, directly or indirectly. This is the significant half of the problem: a caching library should not put a licence condition on its consumers.

Build breakage. Because the dependency is >= 8.10.0, any consumer pinning an older FluentAssertions in their test project gets a hard NU1605 package-downgrade error rather than a warning.

Encountered in a downstream app via:

HallenMedlem.Server
  -> Quilt4Net.Toolkit.Health 1.0.0
    -> Quilt4Net.Toolkit 1.0.0
      -> Tharga.Cache 1.0.0
        -> FluentAssertions (>= 8.10.0)
error NU1605: Detected package downgrade: FluentAssertions from 8.10.0 to 8.8.0.

The consumer had no way to know a caching package would constrain their assertion library version.

Suggested fix

If the reference lives in the library project for test-helper reasons, mark it non-flowing:

<PackageReference Include="FluentAssertions" Version="8.10.0" PrivateAssets="all" />

If it is not used by the library at all — which the assembly scan suggests — remove it from the library project entirely and keep it only in the test project.

Worth checking whether the same reference leaks from any sibling Tharga.* packages built from a shared Directory.Build.props, since that is a common source of this pattern.

Activity

  1. poxet commented on Aug 16, 2026

    @poxet
    ContributorAuthor

    Fixed in #60.

    Your assembly scan was correct — the library never referenced FluentAssertions. Confirmed from the source side too: no using FluentAssertions and no .Should() anywhere under Tharga.Cache/. So it is removed from the library project outright rather than marked PrivateAssets="all"; all the test projects already declared their own reference, so nothing else had to move.

    Verified the way you reported it — packed the project and read the nuspec out of the .nupkg:

    <group targetFramework="net10.0">
      <dependency id="Microsoft.Extensions.Hosting.Abstractions" version="10.0.11" exclude="Build,Analyzers" />
    </group>

    You were right to flag the licensing half as the significant one. It was also visible at runtime — the Xceed community-licence warning printed on every test run of this repo, which is exactly the notice that should never have been reachable from a caching package.

    On your closing suggestion to check the siblings: it was a single stray line in Tharga.Cache.csproj, not inherited from a shared Directory.Build.props. But it did reach all six published packages, since .Redis, .MongoDB, .File, .Blazor and .Mcp all ProjectReference the core — so the fix clears the whole set at once.

    Once you are on the release carrying this, you can drop any FluentAssertions pin or explicit reference you added purely to escape the NU1605. Since the chain ran through Quilt4Net.Toolkit.Health → Quilt4Net.Toolkit → Tharga.Cache, Quilt4Net.Toolkit will need a rebuild against the new version before the dependency stops being passed along to HallenMedlem.Server.

  2. added a commit that references this issue on Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions