Issues with versions of specklecore2

Hi,

I would like to hear if anyone are able to help me.

I have downloaded nuget package Speckle.Core, etc… with SpeckleCore2.dll v.2.3.0.0 a long time ago.
I have used it in my own Revit plug-in project to do simple queries to speckle api (REST/GQL). I use Visual Studio when debugging. It has used to work for a long time.

I have also forked the speckle-sharp repo to my own git, and cloned from there in Visual Studio again couple of years ago. These are two separate solutions; the speckle-sharp and my own solution.
I wanted to start over with clean code for the speckle-sharp solution recently, so I just backed the old project to another branch, and then made a pull-request to get latest version to my git, and then cloned again or made a pull-request in VS to the active branch, overwriting most I would expect. When I view the destination folder for the plug-in, this version holds SpeckleCore2.dll v.2.0.999.0. This corresponds to what is written as file/assembly version when opening core.csproj.
starting Connector2021 in debugging mode works. The two plug-ins are also in separate locations all together.

However, in my own plug-in project, I now get a run-time error, where calling functions in speckle core expects version 2.0.999.0 which has a slightly different structure that do not correspond to what I have coded. I find this strange, since I do not understand where there is such a reference. In my VS project I have a reference to the 2.3.0.0 version of specklecore2.dll from what I can see and understand.

The error message is: Could not load type ‘Speckle.Core.Credentials.ServerInfo’ from assembly ‘SpeckleCore2, Version=2.0.999.0, Culture=neutral, PublicKeyToken=null’
This is only run-time error, and while in the IDE, I get no error since I still use the previous version that I have always used so far, and the IDE/intellisense reflects this.

kind of messy… but I hope maybe someone experienced might have a clue to what went wrong. I could update my nuget packages in my own plug-in project, but I also do not know if this would resolve the issue because of the version numbering, as I would end up with 2.14.3

As a final note:
At some point back in time, before I started testing the code itself, I have probably installed the Speckle Revit Connector plug-in through the speckle manager. It now asks to update from 2.3.0 to 2.14.3. This one I will ignore if it does not have any impact on the aforementioned issues.

Hi @henkon

I think what you’re experiencing is known as “C# DLL Hell” and as you very well said its…

What’s happening there is that only one specific version of any given DLL can be loaded into an application at any given time (and then, cannot be unloaded unless the app restarts).

2.0.999 is the hardcoded development version for any local build. So what I think is happening is that your locally built version of the connector is up to date with the latest release (2.14.3) in regards to changes in the git repo, but your plugin is loading a super old 2.3.0 version.

Note that building the Revit plugin will copy the necessary dlls automatically to the revit locations so that Revit can find them, even if you haven’t “installed” the plugin consciously :smiley: Running a clean operation should delete those folders.

I’m fairly certain that upgrading your plugin to use the latest Core version should get it to work but there are some things I must let you know:

  • If your plugin is designed to work alongside the Speckle connector (I.e. you expect the user to have the connector installed). Then your plugin shouldn’t package SpeckleCore with it, instead it should just assume Speckle would always load core.

There is a problem with this assumption: In many programs, you won’t have control over what loads first. In the case your plugin loads before ours and does not contain SpeckleCore, loading of your plugin will fail :smiling_face_with_tear:

  • If your plugin is designed to work independently of the Speckle connector, then the only solution for you is to always keep it up to date. The issue is similar to above… If you have 2 versions of Core when only one is allowed, whoever is the first one getting loaded would have preference, and the other plugin may fail if there have been breaking changes between versions.

Sadly, most of this is out of our control, and there is no easy perfect solution in any of the cases. I would rather recommend the first option, but I will confess we haven’t gone too deep on any of these use-cases.

Hope this clarifies a bit what’s going on.

Hi @AlanRynne

Thank you for your very quick response, and thorough answer.

Well, my Proof of Concept is to use speckle connector to do what it does best. Why I even downloaded the source code is that I actually need to make a small change somewhere in the code to create shared parameters that can hold the values for the objectId and/or commitid and/or branch returned after send command, to further be able to identify that and then use my own plug-in to query that data for further use of the data.

The two plug-ins are pushed in two different directories, or at least that is how I believed they were
I presume speckle, once I run the speckle-sharp RevitConnector project, it will copy files to "…($appdata)\Autodesk\Revit\Addins\2021\SpeckleRevit2
My own is located in …\ProgramData\Autodesk\ApplicationPlugins\myplugin.bundle\
I do this by just using a post-build event.
Because of this, I was so sure that I could not end in “C# DLL Hell” :slight_smile:

But from what you write that is not the case. So I should really for now try to update the nugets. I could maybe exclude dlls to be copied, since I need to have the dll available in my project so far, since they are two different solutions. Or maybe better to reference the speckle-sharp project itself somehow?

Hopefully I will be able to fix it now anyway. Happy to understand better how things work. Also when I at some point should do a release.

1 Like

Hey @henkon, you’ve fascinated us with what your POC plugin does now. Suppose it runs inside Revit and relies on Speckle Connector to be there. In that case, there is an outside chance that you could reference the running instance of the Speckle Connector with Reflection. But, using Reflection to invoke methods at runtime or dynamically loading assemblies has its own caveats and performance impacts. It’s usually better to have static references at compile time when possible.

Largely this comes down to what you want to be doing.

Updating your NuGet packages is a good start, and excluding redundant DLLs is also a good practice to avoid conflicts. But do keep a keen eye on your references, especially if you’re dealing with different versions of the same library across multiple projects.

If you have forked the Connector code, using our Nugets as a shared resource is tricky. You could namespace and republish them to Nuget, perhaps. Here are the steps you’d need to follow:

  1. Change the Namespace: You would need to refactor the code to change all namespaces to something unique. This will ensure your custom version doesn’t interfere with the original version.
  2. Publish to NuGet: After renaming the namespace, you can compile the library and publish it to NuGet with a different package ID.
  3. Reference Your NuGet Package: In your plugin project, you can remove the original Speckle Connector library and replace it with your custom NuGet package.

This approach, however, has its drawbacks. For one, you would need to maintain your custom library separately and update it each time there are updates to the original Speckle. Because of our fabulously fast release cadence, this may be a lot. And unless you can be sure that no one else will be running your version of the Connector, this may also cause problems.

The .NET clashes DLLs together because despite where the libraries and files are stored on disk, at runtime, it smushes them all together in the same space, but with no loading order control.

Either way, if you want to line up a call to discuss where you are going with this, I’m happy to talk :smiley: