Error loading package

I’m referencing an assembly in my ZT package that is either:

  1. Not available for older versions of the host app (Civil 3D in this case)
    – or –
  2. Is a newer version such that certain members are not available in older versions of the assembly.

Are the only solutions for this to use late binding or build separate package versions for each version of the host app? Right now the library will only partially load for users on older versions, so even portions of the package that don’t rely on the troublesome assembly are not loaded. It seems like Dynamo loads everything up until it hits a build error, and then just stops loading the rest (no idea if that’s how it actually works).

Ideally I’d like for any user to at least be able to load the package, and then nodes that aren’t compatible with their host app version would throw an exception when used.

note, my examples below are for Revit, but the ideas should hold true for Civil3d

The only solution I have seen similar to that is how archilab is released and that creates a ton of issues if you are managing deployments for anyone on multiple versions of the host software.


For my package Rhythm, I elected to separate functionality for later versions and use invoke to fire the commands off right from the DLL. This means the dependencies (for Revit 2022 in my case) don;t actually get referenced in older Revit versions.

Here is sample code:

The Rhythm Revit 2022 code (which becomes its own DLL RhythmRevit2022.dll in the extra folder):

and the actual ZeroTouch code that calls it (in my base Rhythm.dll):

and the invocation utilities: https://github.com/johnpierson/RhythmForDynamo/blob/master/src/Rhythm/Utilities/Utilities.cs

2 Likes

Thanks John, that looks really promising. I’ll give it a go and see if that solves my issues.

What’s your method of testing this? I’m assuming you have Revit 2022 installed, so how do you test if the exception is getting thrown correctly for a user that wouldn’t have Revit 2022?

If I test in a version that is not 2022 the exception is getting raised with the Dynamo utilities.

In Revit we commonly use something like this:

if (revitApplication.VersionNumber != 2022) throw

so I am doing something similar but using the DynamoRevit libraries.

Ah OK, I understand better now. The problem I’ve been having is that there’s an assembly that was originally introduced in Civil 3D 2020.6, but then updated with a bunch of new members in 2022.1. I have 2022.1 installed on my computer and so everything in my package would load fine in 2020.6 because it could still find the reference to the newer assembly version on my computer. So I couldn’t figure out a way to test what a 2020 user might experience without uninstalling 2022 myself, which is a little ridiculous.

I don’t think there is an easy equivalent of Application.VersionNumber for AutoCAD/Civil 3D, so I’ll probably have to dig through the registry to find that info.

@mzjensen Just like @john_pierson mentioned, I have used a little bit different approach to my packages but one that should actually be a good fit for what you are doing. Here’s what the difference really is between the two approaches. Let’s call them:

  • archi-lab.net - Shared Project Approach
  • rhythm- Invoke Method Approach

With the Shared Project Approach, I am creating a version of the package that is built against specific version of Revit, or in your case that would be CAD etc. Because I have multiple Visual Studio projects, I can reference different Nuget pacakges or DLLs to build the project against. That also gives me a quick debugging opportunity in Visual Studio. As I am typing code, Visual Studio checks it against specific version of the DLL/API so it won’t build the project if I try using an API that no longer exists. It makes it super easy to spot deprecated functions etc. Problem is that with that approach, I end up with a set of DLLs for Revit 2020, Revit 2021 and Revit 2022. I have to post and manage each of these versions in the Package Manager, and since now I have multiple flavors of the package users that download it from the Package Manager can and will install Revit 2020 flavor for their 2021 Revit. It happened and will continue to happen, as people either don’t know about these different flavors or just miss it. I still think, it’s a problem or an improvement for the Dynamo development team to find a solution to. This kind of approach should be supported by the package manager.

Anyways, the other approach that @john_pierson is using is also a valid approach, and results in a single package that should work with all flavors of Revit/CAD. I don’t have anything against it. It makes spotting API issues a little less obvious as you kind of have to “know” about them as opposed to letting Visual Studio just tell you about them. It also means that you end up with just one DLL that is built against a specific version of Revit, let’s say 2022, so when that package is downloaded and installed in Revit 2021, you will get Dynamo errors complaining about the version mismatch. It’s purely aesthetic as that error doesn’t do much, but I had enough users complain about it, or ask about it, that I decided to clean that up. Overall it’s a totally valid approach, and makes perfect sense. I used version of that in the past.

Hope this helps.

Here’s source code for archi-lab.net GitHub - ksobon/archilab: this is archi-lab.net dynamo repo

4 Likes

This is not an concern for RevitAPI.dll, RevitAPIUI.dll and a few others since Dynamo 2.10

1 Like

Oh! I didn’t even realize this. So they decided to hide that conflict message instead of making it easy for people to build and manage packages against specific versions. I think this idea was floated before to me so I am not surprised. I would personally prefer a revamp of the Package Manager and better ways to manage multi version packages. It’s fine. Thanks for the info.

1 Like

There are some new things in 2.13 related to package management as well. It even has yours in the screenshot :slight_smile:

As far as I can tell these changes are mostly aesthetic. There are some changes in there to how things are installed, but what I am talking about would be a change to how developers manage their packages. My interest would be in developing a routine that would allow people to easily publish multiple versions of the package and be able to specify which version would be loaded into what host application. If you are familiar with how AutoCAD’s autoloader works, it’s similar to that idea. At the moment it’s highly confusing for people to open Package Manager from Dynamo for Revit 2022, and be presented with version of the package for Revit 2021. It leads to people installing a wrong version. It could have been easily solved just by allowing package to be tagged with what host application and version of that application the package should be made available.

4 Likes