I’m developing a dynamo package that reference a nugetpackage which reference another dll (the conflicted dll). Another Revit plugin also use the same dll and it create a conflict.
Most existing solutions use AssemblyResolve to load the correct updated dll. So far I have tried these and they do not work for me
I have seen solutions out there for Revit plugin but I’m developing dynamo package so I do not know where to specify the AssemblyResolve for dynamo development.
I tried to do sth similar to this. So I call AssemblyResolve right before I used the third party dll. Basically right before I use the code inside the conflicted dll. That did not work either The Building Coder: RvtVa3c Assembly Resolver
I tried using a seperate AppDomain but I thinnk Revit only allow one appDomain that Revit uses. So I cannot use a seperate AppDomain either.
Hi. the third party package is a self developed package. the conflicted dll it reference is System.Diagnostics.DignosticSource.dll. The one i used is version 6, it is conflicted with version 4.
I dont think which dll matter. The conflicted reference error is generic for any dll
The nuget package that I developed rely on a suite of tools and their versions need to match. Also I’m looking for a comprehensive solution. It is just an example that there’s one package happens to have System.Diagnostic version 4. What if the user happens to have two Revit plugins, one use System.Diagnostic version 4 and another one use version 5? Simply downgrading/upgrading our own version would not solve the overall problem
Maybe the problem could be solved if there’s a way I can specify which Dll to load when Dynamo start? Similar to how OnStartUp() works for Revit plugin.
Assembly merging only works if the types that you merge are modified to be unique, usually the merging tools like costura or il merge do not do this. We have a simple tool that we have written for this, it generates a new assembly with new type names for each type (adds a new namespace) and renames the assembly. Dynamo/src/Tools/AssemblyRenamerCLI at master · DynamoDS/Dynamo · GitHub -
appDomain would work, but then you need to serialize and deserialize between domains.
loading your assembly first - this works when things are loaded in a certain order, and only sometimes, it depends on how the other addin is loading their assemblies.
loading your assembly with assembly resolve - again, it can work, but anyone else can also inject an assembly resolve event, and they are called in the order they are added, so a previous assembly resolve handler from another addin might win.
loading the binary from the GAC can actually work… but you would have to install this binary into the GAC… if it’s not already in there.
…
There are more things we’ve tried or others have, this is not an exhaustive list, it’s just what I can recall - but first questions first:
What issues do you actually see because of the conflict? Anything?
Have you checked what modules actually get loaded by debugging Revit at runtime?
Thank you Michael for a very comprehensive answer. Option 2 and 5 sound good (what is GAC though?). Do you have an example for them? I tried option 2 without serializing and that didnt work, and not sure how this solution should work
This is a good question. The sequence of loaded module is perplexing to me. The sequence is as such.
When I start Revit along with the debugger , no System.Diagnostic module is loaded
2.When I start Dynamo. The correct dll (the dll I use) is loaded
No other System.Diagnostic module is loaded when i drop the node.
It’s only when line 47 is called, the line that actually use the third party package is used then System.Diagnostics ver 4 module is reported loaded and cause the error.
The GAC Global Assembly Cache - .NET Framework | Microsoft Docs is the global assembly cache - in general the recommendation from MS is NOT to install things here, and I would agree that installing a Microsoft assembly there if it’s not already located there was probably not avoided for a reason.
I would give the renamer a shot if you really need it, though I still don’t understand what error you actually encounter.
Another option I have seen addin developers use is to take the source and manually change the type names by wrapping in one big namespace.
What do you mean by renamer? renaming and wrapping System.Diagnostics namespace? That’s one option but there are probably more dlls that are going to have conflicts. But maybe I can give it a try
Do you have any example for using appDomain (solution number 2 in your suggestion) ? I thought Revit only allow one appDomain to work with Revit?
Anyway, when i step through line 47. The error is this. Thanks Michael
Also just to clarify. System.Diagnostics.Diagnostics.dll is not a reference that I used. It is a required dependency of a nuget package that I used so I do not have control over it.
If we use renaming, that means if we have 4 or 5 dependencies that clash we will have to rename all the namespaces in that 4 or 5 dll. The problem is we will not even know which are the dlls that we are going to clash. This depends very much on the Revit plugins each user have in their machine. I’m just using this System.Diagnostics.Diagnostics dll as an example.
Any time you develop for a system you need to confirm that your code runs in that system. This is the case for Revit add-ins conflicting with each other, just as much as it is Dynamo nodes conflicting with each other and Revit add-ins.
The only way to ensure you never conflict is to only use your own stuff, or ensure that you always “rename” as noted above. If the namespace goes from ‘somepackage’ to ‘myHappyDynamoPackage’ the issue is resolved. This is difficult and time consuming to set up, but it is the only way you can ensure that your 3rd or 4th (nth?) party dependencies don’t conflict.
I believe that someday when we get to .net 6 this gets a good bit simpler, but that’s a ways out yet.