All F# plugins fail to load on .NET 8

I have several Plugins written in F#, most notably Fesh.

None of them can currently be loaded in Rhino with .NET 8 runtime.

(Rh8 SR25)

In the previous versions of Rh8 this has been working. I am not sure how to revert to older service releases for testing.

In .NET Framework 48 all is good

See here is a minimal F# plugin for testing and errors: GitHub - goswinr/RhPluginTest: A minimal Rhino Plugin template for .NET 8.0 and F#

Did anyone successfully load an F# plugin on .NET 8 ?

System.IO.FileNotFoundException: Could not load file or assembly 'FSharp.Core,
...

F# is a nuget package and likely not part of the std library anymore…

Thanks Tom, you got me to rethink the problem.
Normally in the .NET 8 runtime dependencies should be loaded from *.deps.json file in the same folder.
My net8.0 Revit 2025 plugin works like that.

FSharp.Core is in the *.deps.json:

{
  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v8.0",
    "signature": ""
  },
  "compilationOptions": {},
  "targets": {
    ".NETCoreApp,Version=v8.0": {
      "RhPluginTest/9.9.9": {
        "dependencies": {
          "FSharp.Core": "8.0.403"
        },
        "runtime": {
          "RhPluginTest.rhp": {}
        }
      },
      "FSharp.Core/8.0.403": {
        "runtime": {
          "lib/netstandard2.1/FSharp.Core.dll": {
            "assemblyVersion": "8.0.0.0",
            "fileVersion": "8.4.324.52602"
          }
        }
      }
    }
  },
  "libraries": {
    "RhPluginTest/9.9.9": {
      "type": "project",
      "serviceable": false,
      "sha512": ""
    },
    "FSharp.Core/8.0.403": {
      "type": "package",
      "serviceable": true,
      "sha512": "sha512-ldNIn4IksrJL/X3rF4R/y9pa3RmwkcGYQ3xFMdbJj8dJ9Q49J735m6sMy3MbCK9gj3YoCsxlyFeExCiNDy3gHQ==",
      "path": "fsharp.core/8.0.403",
      "hashPath": "fsharp.core.8.0.403.nupkg.sha512"
    }
  }
}

The Rhino .NET 8 runtime doesn’t seem to load dependencies from *.deps.json.

Is that the correct assessment of the bug @dale ?

The workaround:
If I copy the file to the output by adding this to the *.fsproj:

    <PackageReference
      Update="FSharp.Core"
      Version="8.0.403"
      GeneratePathProperty="true"/>

    <Content
      Condition="'$(TargetFramework)' != 'net48'"
      Include="$(PkgFSharp_Core)/lib/netstandard2.1/FSharp.Core.dll"
      CopyToOutputDirectory="Always" />

it works.
:smiley:

1 Like

or just use dotnet publish --framework net8.0-windows --self-contained

1 Like

Self contained will include all dependencies for NET Core. It will be duplicated and potentially dangerous if you provide it with your plugin, since Rhino comes with NET 8 itself (but in a different minor version). However you can try to use -p:PublishTrimmed=true (or as an option in the csproj) to only get the relevant parts of NET 8 used in your plugin. You just need to be aware not to use Reflection. In this case its dangerous to publish trimmed.

1 Like

@TomTom I see what you mean,

Oddly using --self-contained does not include the full net8 runtime. When I building locally. And using PublishTrimmed fails to build in F#. It complains about a missing assembly entry point. Fair enough, Rhino plugins are libraries, they don’t have an entry point like standalone exe apps. That missing entry point might also be the reason why --self-contained does not include the full runtime. I didn’t test. At least I have a working solution. I had to do some copying of files to get the right directory structure for Rhino YAK. The build process is here: release.yml