Adding a custom transport node in Grasshopper

Hi guys,

I’m writing a custom transport for Speckle, which I want to use in a Grasshopper script.
I have installed the Speckle.Core NuGet package and it all and good.
I compile and tries to debug/test in Grasshopper, but I’m met with this error when I load Grasshopper.

My transport component works, but standard Speckle components stopped working.
Have anyone ran into this before?


Heya! It might be that there are conflicting versions of Core being loaded. Welcome to dll hell. You could try to not bundle it with your plugin/transport node, and rely on the installed version.

On a side note, cool that you’re building a new transport! You’re probably the first one to do so outside the speckle team; we’re dying inside to know what the usecase is!

Hmm, seems a bit troublesome to do so, but I’ll get it a try.

I have some data/files that I want to upload along with my 3D model. Instead of putting the data/files into the stream, (I found the serialization quite slow and the 3D viewer slows down as well), I thought to upload them to Azure Blob Storage and just reference the urls in the Speckle objects.

Gotcha! Super interesting use case - and thanks for sharing it. We’ve actually just merged in to latest a stream blob storage API which will allow you to do just that, and there are plans to integrate that in a way that won’t slow down the viewer.

In the meantime, let us know if we can help debugging the whole dll mess. @AlanRynne might have some extra insights on that front!

1 Like

@dimitrie are you saying if I wait a bit, the functionality I need will soon come to a SpeckleManager near me? :slight_smile:
Do you have an ETA on it?

We don’t have an ETA, hence why I don’t want to leave you astray and derail current efforts. Where we’re coming from is texture support (again, just image blobs in materials).

Would you be willing to test things out with us when we’re ready for it?

Hey @chrk, this is an interesting use-case, I’m actually in the middle of investigating what would be our suggested “best practices” to do this kind of thing so you come at the right time!

As far as I can tell, you should not include any of our .dll files in your build folder. Instead, you should rely on speckle being installed along-side our connector.

Meaning, usually you’d just need the gha file, and whatever dependencies are specific to your use-case.

I think loading priority shouldn’t be an issue in Grasshopper, but if you run into any issue let me know.

@AlanRynne how would I go about excluding the Speckle .dlls in the build output?
I have included the Speckle.Core in my .csproj file like this.

        <PackageReference Include="Speckle.Core" Version="2.5.2"/>

Yeah, I can test things out, when you have it.
Is it possible to coordinate our efforts? I’m not so keen on developing something that becomes deprecated shortly after I’m done writing it.

Of course! I’ll ping you here and/or email once we’ve got this going :slight_smile:

1 Like

Hey @chrk,

As far as I’m aware, if your using SDK Style projects, you should be good to go by just setting the ExcludeAssets property in each of the packages to runtime.

As such:

    <PackageReference Include="Speckle.Objects" Version="2.5.2"  ExcludeAssets="runtime"/>
    <PackageReference Include="Speckle.Core" Version="2.5.2"  ExcludeAssets="runtime"/>

This will force the IDE to exclude anything coming from these packages into your build folder, but any other “non-speckle related” package will be copied as usual.

It may also be the case where you’re build folder gets poluted with some SQLite.Interop.dll files. In that case, also set PrivateAssets="all" in both packages alongside the ExcludePackages property.

    <PackageReference Include="Speckle.Objects" Version="2.5.2"  ExcludeAssets="runtime" PrivateAssets="all"/>
    <PackageReference Include="Speckle.Core" Version="2.5.2"  ExcludeAssets="runtime" PrivateAssets="all"/>

Hope that does the trick! But let us know how it goes anyway :slight_smile:

1 Like

Thanks @AlanRynne that worked!

1 Like

Great! Did you end up needing to add the PrivateAssets flag too? :slight_smile:

I included PrivateAssets but it doesn’t seem to have any effect. I still get the SQLite.Interop.dll files in the build folder.
It doesn’t seem to conflict with anything though

Oh that’s interesting, I tried it on my end and it seemed to do the trick. What framework are you targeting? I tested on net48 and netstandard2.0 :+1:t3:

I’ll be happy to test on whatever you were building to see what would be needed for a clean build folder.

Although, as you said, SQLite.Interop may not have any effect in there, as it’s a dependency of core and would get loaded from SpeckleCore2.dll location. :slight_smile:

Ideally, we’d still want developers to have a clean build to prevent any conflicts. :+1:

1 Like

I tried to clean the build folder, but SQLite was still generated.
My .csproj file looks like this:

<Project Sdk="Microsoft.NET.Sdk">

        <Description>Description of GrasshopperTemplate</Description>

        <PackageReference Include="Azure.Identity" Version="1.6.0" />
        <PackageReference Include="Azure.Storage.Blobs" Version="12.12.0" />
        <PackageReference Include="Grasshopper" Version="7.4.21078.1001" IncludeAssets="compile;build" />
        <PackageReference Include="Speckle.Core" Version="2.5.2" ExcludeAssets="runtime" PrivateAssets="all"/>
        <PackageReference Include="System.Reactive.Windows.Forms" Version="5.0.0" />
        <PackageReference Include="System.Text.Json" Version="6.0.5" />

      <Folder Include="Resources" />

      <EmbeddedResource Update="Resources.resx">

      <Compile Update="Resources.Designer.cs">

    <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Message Importance="High" Text="Building $(Configuration)" />
        <CallTarget Condition="'$(Configuration)' == 'Debug'" Targets="AfterBuildDebug" />
        <CallTarget Condition="'$(Configuration)' == 'Release'" Targets="AfterBuildRelease" />
    <Target Name="AfterBuildDebug">
            <SourceFiles Include="$(TargetDir)**\*.*" />
        <Message Importance="High" Text="DEBUG copy from $(TargetDir) to $(AppData)\Grasshopper\Libraries\$(ProjectName)" />
        <RemoveDir Directories="$(AppData)\Grasshopper\Libraries\$(ProjectName)" />
        <Copy SourceFiles="@(SourceFiles)" DestinationFiles="$(AppData)\Grasshopper\Libraries\$(ProjectName)\%(RecursiveDir)%(Filename)%(Extension)" />
    <Target Name="AfterBuildRelease">
            <SourceFiles Include="$(TargetDir)**\*.dll;$(TargetDir)**\*.gha" />
        <Message Importance="High" Text="RELEASE copy from $(TargetDir) to $(SolutionDir)Release\" />
        <Delete Files="$(SolutionDir)Release\$(ProjectName)" />
        <Copy SourceFiles="@(SourceFiles)" DestinationFiles="$(SolutionDir)Release\$(ProjectName)\%(RecursiveDir)%(Filename)%(Extension)" />

    <PropertyGroup Condition="$(Configuration) == 'Debug' AND $([MSBuild]::IsOSPlatform(Windows))">
        <StartProgram>C:\Program Files\Rhino 7\System\Rhino.exe</StartProgram>

1 Like