Thank you for your appreciation.
The development added some background information to the ticket REVIT-160709 [RVTPR-00662: AddinManager Error for Obfuscated Add-ins] which on one hand is pretty obvious, on the other may point the way to an effective workaround for some cases:
I can confirm that the fix that was submitted to dev last week is complete. The null check on version string submitted last week is the only fix needed and we should be good.
The `TypeLoadException` issue on the customer add-in can be explained as below. I can reproduce this on a fresh add-in using the `.NET Reactor` obfuscation tool.
Revit Addins register class names for `IExternalCommand`, `IExternalCommandAvailability` `IExternalApplication` etc. as a string. For example
PushButton pushButton = ribbonPanel.AddItem(
new PushButtonData("MyButton", "Button",
Assembly.GetExecutingAssembly().Location,
"MyNamespace.MyCommandClass") as PushButton;
Revit then looks up `"MyNamespace.MyCommandClass"` in the assembly dll using `System.Reflection`. This all works well in an regular (unobfuscated) addin, for `public` as well as `internal` class `"MyNamespace.MyCommandClass"`.
If we run the `".NET Reactor"` obfuscation tool on the above code as is, it also works for both `public` as well as `internal` class `"MyNamespace.MyCommandClass"`. For a public class `"MyNamespace.MyCommandClass"`, the obfuscator will keep the same class name and its reference in the above code will also be retained as is. If the class `"MyNamespace.MyCommandClass"` was `internal`, then the obfuscation tool will mangle the class name and correctly fix the reference above in the `PushButtonData` constructor. It will fix the reference as long as it can find the string `"MyNamespace.MyCommandClass"` as is.
So far so good.
However, in a case where the class `"MyNamespace.MyCommandClass"` is `internal` and the class name is broken like this (and there could be valid reasons to be doing this or similar):
string str1 = "MyNamespace";
string str2 = "MyCommandClass";
PushButton pushButton = ribbonPanel.AddItem(
new PushButtonData("MyButton", "Button",
Assembly.GetExecutingAssembly().Location,
str1 + str2) as PushButton;
In such a case, the obfuscation tool will fail to connect the dots. Revit will end up looking for "MyNamespace.MyCommandClass", but the `internal` class would have been named as something else. To avoid this, one could either provide the full class name as is `"MyNamespace.MyCommandClass"` or make the class be public.
We shall merge the original fix to an update release of Revit 2021 as well.
Best regards,
Jeremy