Proper way to handle App.config bindingRedirects in Revit Add-In

Anonymous

Proper way to handle App.config bindingRedirects in Revit Add-In

Anonymous
Not applicable

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!

0 Likes
Reply
Accepted solutions (2)
4,112 Views
11 Replies
Replies (11)

jeremytammik
Autodesk
Autodesk

Dear Klanea,

 

Good question! Thank you!

 

I'll check with the development team and see what they have to say.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

jeremytammik
Autodesk
Autodesk

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

 

http://stackoverflow.com/questions/1373100/how-to-add-folder-to-assembly-search-path-at-runtime-in-n...

 

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



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

jeremytammik
Autodesk
Autodesk
Accepted solution

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



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Anonymous
Not applicable
Accepted solution

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!

0 Likes

Anonymous
Not applicable

@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!

0 Likes

it
Explorer
Explorer

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!

0 Likes

Anonymous
Not applicable

Oops, sorry, was logged into the wrong account. As you may have guessed, the above is also me.

0 Likes

infoGQE4W
Explorer
Explorer

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?

0 Likes

RitaRolAguiar
Contributor
Contributor

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?

 

0 Likes

jeremy_tammik
Autodesk
Autodesk

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.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open