Isolate Autodesk Add-Ins With the 'Isolator.Fody' NuGet Package
Resolve version conflicts by simply adding an attribute to the classes.

Search for a command to run...
Resolve version conflicts by simply adding an attribute to the classes.

No comments yet. Be the first to comment.
A technical series exploring dependency isolation for Autodesk add-ins, using `AssemblyLoadContext` to solve versioning conflicts.
Solve version conflicts once and for all.
Autodesk implemented it so you don't have to.

Solve version conflicts once and for all.

Stepping Through iLogic Rules Line-by-Line

Solve version conflicts once and for all.

Autodesk add-ins previously allowed the use of NuGet package/assembly versions that differ from the ones bundled within the Autodesk software. However, with the framework upgrade to .NET 8, this no longer worked out of the box and caused version conflicts.
This article will demonstrate one way to resolve the version conflict by using the 'Isolator.Fody' NuGet package to automatically isolate the add-in’s dependencies in a separate container using AssemblyLoadContext. All it takes is adding the [Isolator] attribute to the class.
A full Inventor and Vault sample application can be found on GitHub.
Previous articles have explained how to do this by directly modifying the add-in architecture and not referencing an external NuGet package.
- It's the runtime's provider for locating and loading dependencies. Whenever a dependency is loaded, an AssemblyLoadContext instance is invoked to locate it.
- AssemblyLoadContext provides a service of locating, loading, and caching managed assemblies and other dependencies.
- To support dynamic code loading and unloading, it creates an isolated context for loading code and its dependencies in their own AssemblyLoadContext instance.
Isolator.Fody NuGet package reference.WeaverConfiguration settings with the SkipIsolator set to false for an isolated AssemblyLoadContext or true for the default add-in behavior.<ItemGroup>
<PackageReference Include="Isolator.Fody" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>build; compile</IncludeAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<WeaverConfiguration>
<Weavers>
<Isolator />
</Weavers>
</WeaverConfiguration>
</PropertyGroup>
[Isolator] attribute to classes that need to use the add-in's NuGet package versions instead of Autodesk's bundled versions.[Isolator] attribute to classes that interact with Autodesk COM objects (ex. Inventor.Application, ButtonDefinition, ribbon UI code). COM interop requires the code to run in the default AssemblyLoadContext; isolating these classes will cause System.ArgumentException marshaling errors.[Isolator]-marked class.// CANNOT isolate. Uses Inventor COM objects.
internal class MyButton : Button
{
protected override void ButtonDefinition_OnExecute(NameValueMap context)
{
// Delegate to an isolated class for dependency-specific work.
AssemblyInspector inspector = new();
string result = inspector.DoIsolatedWork();
}
}
// Safe to isolate. No COM interop.
[Isolator]
internal class AssemblyInspector
{
public string DoIsolatedWork()
{
// Uses the add-in's version of Serilog, not Inventor's.
Serilog.Log.Information("This runs in the isolated context");
return typeof(Serilog.Log).Assembly.GetName().Version?.ToString() ?? "unknown";
}
}
<Isolator SkipIsolator='true' /> can replace <Isolator /> in the project file to temporarily disable isolation for debugging. Since false is the default, <Isolator /> and <Isolator SkipIsolator='false' /> are equivalent. typeof() calls for assemblies to be isolated must be placed inside the [Isolator]-marked class. If a Type is passed from a non-isolated class, it will resolve to the default context's version.ILTemplate.cs from a non-existent path (ex. D:\a\Isolator.Fody\...). This is the build server path embedded in the library's debug symbols and can be safely dismissed.AppDomain is used instead of AssemblyLoadContext.AppBundle with the Automation API.