Hello,
I'm writing a Revit add-in that depends on a number of third party DLLs. Several of these DLLs (updated to the latest versions via NuGet) are compiled against older .NET assemblies, requiring use of bindingRedirects to redirect the .NET runtime to the appropriate assembly version. This workaround is appropriate for developers producing .exe executables, but not for those producing DLLs (including Revit Add-Ins - source), as bindingRedirects are run for the hosting application only (Revit.exe). I was able to temporarily solve this problem by appending my Add-In's bindingRedirects to Revti.exe.config. That said, requiring Add-Ins to make modifications to Revit.exe.config seems like a dangerous, brittle solution for production environments. Is there a more robust way to handle this bindingRedirect dependency problem for Revit Add-Ins? Should IExternalApplications modify/revert Revit.exe.config changes onStartup/onShutdown?
Thanks in advance!
Solved! Go to Solution.
Solved by jeremytammik. Go to Solution.
Dear Klanea,
Good question! Thank you!
I'll check with the development team and see what they have to say.
Cheers,
Jeremy
One colleague suggests the following:
Assembly loading can be controlled from source code using .NET AppDomain.AssemblyResolve event described here:
https://msdn.microsoft.com/en-us/library/ff527268(v=vs.110).aspx
Sample code for IExternalApplication can be:
public Result OnStartup( UIControlledApplication a ) { System.AppDomain currentDomain = System.AppDomain.CurrentDomain; currentDomain.AssemblyResolve += new ResolveEventHandler( currentDomain_AssemblyResolve); //… } System.Reflection.Assembly currentDomain_AssemblyResolve( object sender, ResolveEventArgs args ) { //… }
That reminds me that I implemented such assembly resolvers myself now and then in the past, e.g.:
http://thebuildingcoder.typepad.com/blog/2014/05/rvtva3c-assembly-resolver.html
Does that help solve the issue for you?
Cheers,
Jeremy
Some more news on this, both good and bad, or maybe both:
1. First, The Revit development team is loath to provide any formal recommendation. There are several possible approaches and we cannot be responsible for any use of a wrong one. We have (and still do) used assembly resolvers ourselves. That does not mean it is a universal solution. It may cause complications, for the event may possibly be raised for more assemblies then those the user actually cares about. Therefore, we can only say that assembly resolvers provide one possible way worth exploring.
2.Secondly, using an assemblyBinding redirect is a bit, well, dictatorial. It’s telling every part of Revit and its associated modules that they *must* use a certain version of a specified assembly. This doesn’t always have positive results.
3. Third, we have seen issues with third-party developers editing Revit.exe.config. When we ship subsequent official patches, upgrades, etc. to the field, the installer software will not overwrite/upgrade Revit.exe.config if it has been dirtied since its original installation; in such cases, the upgrade fails (and---what is worse---fails silently). When customer support eventually deduces the problem and provides the user with a new Revit.exe.config for manual overwriting, then whatever add-ons/add-ins/third-party apps made the original edits will be broken, so for the user it’s yet another call to somebody’s customer support to get that worked out.
With all this in mind, we would really like to help third-party developers find a solution that does *not* include editing Revit.exe.config. Unfortunately, we don’t have all the answers at this point, but we plan to pursue this further because of the reasons stated above, so please keep us up to date with your requirements, research and results.
Thank you!
Cheers,
Jeremy
Hi Jeremy,
Many thanks for your prompt and thorough responses! These are very helpful. Option 1 seems to have resolved the present assembly redirect problem without Revit.exe.config munging. I'll keep you posted if I find alternatives solutions, as I too cringe at the thought of third party developers editing Revit.exe.config files directly.
Give my thanks to the Revit dev team for their support on this. All best!
@jeremytammikStill working 5 years later! Thanks! Just wanted to check in as you allude here to a continued search for better methods of doing this. Is this (custom assembly resolvers) still the best way to get Revit to load an assembly that is refusing to load otherwise? Thanks!
Thank you for the appreciation and congratulations that it fulfils your needs.
Here are some recent related discussions of other approaches:
Jeremy,
Thanks for your reply. I think I must be missing something, though, because I can't figure out how your links relate to workarounds for binding redirects not working in the context of a Revit addin. As far as I can tell they relate to loading updated dlls in the Addin Manager. As it happens, I hadn't heard about the Addin Manager, so I'm super excited about that, but not sure how to apply those links to the issue above. Thanks!
I doubt assembly resolve event solves anything, maybe in specific cases, but since it does not get even called in Application.OnStartup where I am doing stuff with assemblies that creates actual conflict (Missing method exception for serilog sinks for instance). Sometimes there is apparently no conflict and just method is missing in older version that gets loaded instead of referenced one but resolve event does not fire. There does not seem to be a way how force to use the one I referenced. Downgrading the packages is not an answer, there can be other custom plugins with different versions as well. It just crashes regardless of any assembly resolve event subscribed. Plus you never know which ones will be in conflict so you would have to make it for all assembly dependencies you have just to avoid any possible conflict. Any other workarounds?
Hi @jeremytammik , I would like to know if there are any news developments on this?
I'm facing a similar issue, to this post, where I want to use the Azure.Storage.Blob package in my revit plugin, however, Azure.Storage.Blob requires a different System.Diagnostics.DiagnosticSource version than Revit. Revit 2023 requires System.Diagnostics.DiagnosticSource version 4.0.1.0. Have you ever encountered this issue?
No new developments, no, but similar issues such as yours keep popping up and the various solutions discussed above and in the links still apply unchanged. Assembly resolver, IPC to disentangle etc. I cannot tell which is the best way to go for you.
Can't find what you're looking for? Ask the community or share your knowledge.