<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Tyler Warner's Software Dev Blog]]></title><description><![CDATA[Tyler Warner's Software Dev Blog]]></description><link>https://tylerwarner.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 12:04:40 GMT</lastBuildDate><atom:link href="https://tylerwarner.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Isolate Autodesk Add-Ins With the 'Isolator.Fody' NuGet Package]]></title><description><![CDATA[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 conf...]]></description><link>https://tylerwarner.dev/assemblyloadcontext-for-autodesk-addins-with-isolatorfody</link><guid isPermaLink="true">https://tylerwarner.dev/assemblyloadcontext-for-autodesk-addins-with-isolatorfody</guid><category><![CDATA[autodesk ]]></category><category><![CDATA[Autodesk Inventor]]></category><category><![CDATA[#autodesk-vault]]></category><dc:creator><![CDATA[Tyler Warner]]></dc:creator><pubDate>Wed, 21 Jan 2026 23:26:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769599929392/1c82a99c-562a-4b5e-9fea-df66d1095ca5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>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.</p>
<p>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 <code>AssemblyLoadContext</code>. All it takes is adding the <code>[Isolator]</code> attribute to the class.</p>
<p>A full <a target="_blank" href="https://github.com/tylerwarner33/autodesk-inventor-assembly-load-context-fody">Inventor</a> and <a target="_blank" href="https://github.com/tylerwarner33/autodesk-vault-assembly-load-context-fody">Vault</a> sample application can be found on GitHub.</p>
<p>Previous articles have explained how to do this by directly modifying the add-in architecture and not referencing an external NuGet package.</p>
<h2 id="heading-what-is-assemblyloadcontexthttpslearnmicrosoftcomen-usdotnetcoredependency-loadingunderstanding-assemblyloadcontext">What is <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext">AssemblyLoadContext</a>?</h2>
<blockquote>
<ul>
<li>It's the runtime's provider for locating and loading dependencies. Whenever a dependency is loaded, an AssemblyLoadContext instance is invoked to locate it.</li>
<li>AssemblyLoadContext provides a service of locating, loading, and caching managed assemblies and other dependencies.</li>
<li>To support dynamic code loading and unloading, it creates an isolated context for loading code and its dependencies in their own AssemblyLoadContext instance.</li>
</ul>
</blockquote>
<h2 id="heading-how-to-update-the-add-in">How to update the add-in?</h2>
<h3 id="heading-update-project-csproj-file">Update Project (.csproj) File</h3>
<ul>
<li>Add the <code>Isolator.Fody</code> NuGet package reference.</li>
<li>Add the <code>WeaverConfiguration</code> settings with the <code>SkipIsolator</code> set to <code>false</code> for an isolated AssemblyLoadContext or <code>true</code> for the default add-in behavior.</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Isolator.Fody"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"1.0.0"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>build; compile<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">WeaverConfiguration</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Weavers</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Isolator</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Weavers</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">WeaverConfiguration</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>
</code></pre>
<h3 id="heading-update-classes">Update Classes</h3>
<ul>
<li>Add the <code>[Isolator]</code> attribute to classes that need to use the add-in's NuGet package versions instead of Autodesk's bundled versions.</li>
<li>Do <strong>NOT</strong> add the <code>[Isolator]</code> attribute to classes that interact with Autodesk COM objects (ex. <code>Inventor.Application</code>, <code>ButtonDefinition</code>, ribbon UI code). COM interop requires the code to run in the default <code>AssemblyLoadContext</code>; isolating these classes will cause <code>System.ArgumentException</code> marshaling errors.</li>
<li>If a class needs both COM interop and isolated dependencies, keep the COM code in a non-isolated class and delegate the isolated work to a separate <code>[Isolator]</code>-marked class.</li>
</ul>
<pre><code class="lang-csharp"><span class="hljs-comment">// CANNOT isolate. Uses Inventor COM objects.</span>
<span class="hljs-keyword">internal</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MyButton</span> : <span class="hljs-title">Button</span>
{
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ButtonDefinition_OnExecute</span>(<span class="hljs-params">NameValueMap context</span>)</span>
    {
        <span class="hljs-comment">// Delegate to an isolated class for dependency-specific work.</span>
        AssemblyInspector inspector = <span class="hljs-keyword">new</span>();
        <span class="hljs-keyword">string</span> result = inspector.DoIsolatedWork();
    }
}

<span class="hljs-comment">// Safe to isolate. No COM interop.</span>
[<span class="hljs-meta">Isolator</span>]
<span class="hljs-keyword">internal</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AssemblyInspector</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> <span class="hljs-title">DoIsolatedWork</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-comment">// Uses the add-in's version of Serilog, not Inventor's.</span>
        Serilog.Log.Information(<span class="hljs-string">"This runs in the isolated context"</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span>(Serilog.Log).Assembly.GetName().Version?.ToString() ?? <span class="hljs-string">"unknown"</span>;
    }
}
</code></pre>
<h2 id="heading-notes">Notes</h2>
<ul>
<li><code>&lt;Isolator SkipIsolator='true' /&gt;</code> can replace <code>&lt;Isolator /&gt;</code> in the project file to temporarily disable isolation for debugging. Since <code>false</code> is the default, <code>&lt;Isolator /&gt;</code> and <code>&lt;Isolator SkipIsolator='false' /&gt;</code> are equivalent. </li>
<li>Any <code>typeof()</code> calls for assemblies to be isolated must be placed <strong>inside</strong> the <code>[Isolator]</code>-marked class. If a <code>Type</code> is passed from a non-isolated class, it will resolve to the default context's version.</li>
<li>When debugging, Visual Studio may prompt to find source files like <code>ILTemplate.cs</code> from a non-existent path (ex. <code>D:\a\Isolator.Fody\...</code>). This is the build server path embedded in the library's debug symbols and can be safely dismissed.</li>
<li>This add-in format is compatible with Inventor versions using .NET Framework 4.8 or .NET 8.  In .NET Framework, <code>AppDomain</code> is used instead of <code>AssemblyLoadContext</code>.</li>
<li>This add-in format is compatible and works as an <code>AppBundle</code> with the <a target="_blank" href="https://aps.autodesk.com/en/docs/design-automation/v3/developers_guide/overview/">Automation API</a>.</li>
</ul>
<h2 id="heading-references">References</h2>
<ul>
<li>NuGet Package: <a target="_blank" href="https://www.nuget.org/packages/Isolator.Fody">Isolator.Fody</a></li>
<li>GitHub Repo: <a target="_blank" href="https://github.com/ricaun-io/Isolator.Fody">Isolator.Fody</a></li>
<li>Microsoft Learn - <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext">System.Runtime.Loader.AssemblyLoadContext</a></li>
<li>GitHub - dotnet - <a target="_blank" href="https://github.com/dotnet/coreclr/blob/v2.1.0/Documentation/design-docs/assemblyloadcontext.md">AssemblyLoadContext.md</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to Use AssemblyLoadContext for Isolating Vault Addin Dependencies]]></title><description><![CDATA[Autodesk Vault previously allowed add-ins to use NuGet package/assembly versions that differ from the ones bundled with Vault. However, with Autodesk Vault 2026 and the framework upgrade to .NET 8, this no longer worked out of the box and caused vers...]]></description><link>https://tylerwarner.dev/assemblyloadcontext-for-vault-addins</link><guid isPermaLink="true">https://tylerwarner.dev/assemblyloadcontext-for-vault-addins</guid><category><![CDATA[#autodesk-vault]]></category><dc:creator><![CDATA[Tyler Warner]]></dc:creator><pubDate>Fri, 16 Jan 2026 11:35:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769682369993/269b10c8-e578-4e50-acd8-34f5e6e231bc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Autodesk Vault previously allowed add-ins to use NuGet package/assembly versions that differ from the ones bundled with Vault. However, with Autodesk Vault 2026 and the framework upgrade to .NET 8, this no longer worked out of the box and caused version conflicts.</p>
<p>This article will demonstrate one way to resolve the version conflict by isolating the add-in’s dependencies in a separate container using <code>AssemblyLoadContext</code>.</p>
<p>A <a target="_blank" href="https://github.com/tylerwarner33/autodesk-vault-assembly-load-context">full sample application</a> can be found on GitHub.</p>
<h2 id="heading-what-is-assemblyloadcontexthttpslearnmicrosoftcomen-usdotnetcoredependency-loadingunderstanding-assemblyloadcontext">What is <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext">AssemblyLoadContext</a>?</h2>
<blockquote>
<ul>
<li>It's the runtime's provider for locating and loading dependencies. Whenever a dependency is loaded, an AssemblyLoadContext instance is invoked to locate it.</li>
<li>AssemblyLoadContext provides a service of locating, loading, and caching managed assemblies and other dependencies.</li>
<li>To support dynamic code loading and unloading, it creates an isolated context for loading code and its dependencies in their own AssemblyLoadContext instance.</li>
</ul>
</blockquote>
<h2 id="heading-how-to-update-the-add-in">How to update the add-in?</h2>
<h3 id="heading-add-isolatediexplorerextensioncs">Add <code>IsolatedIExplorerExtension.cs</code></h3>
<p>This is used as the new entry point into the add-in. It is a wrapper around the <code>IExplorerExtension</code>. It adds additional functionality behind the scenes but still exposes all methods called automatically by Vault.</p>
<ul>
<li><code>OnStartup(IApplication application)</code> =&gt; <code>Startup()</code></li>
<li><code>OnLogOn(IApplication application)</code> =&gt; <code>LogOn()</code></li>
<li><code>OnLogOff(IApplication application)</code> =&gt; <code>LogOff()</code></li>
<li><code>OnShutdown(IApplication application)</code> =&gt; <code>Shutdown()</code></li>
<li><code>CommandSites()</code> =&gt; <code>OnCommandSites()</code></li>
<li><code>CustomEntityHandlers()</code> =&gt; <code>OnCustomEntityHandlers()</code></li>
<li><code>DetailTabs()</code> =&gt; <code>OnDetailTabs()</code></li>
<li><code>DockPanels()</code> =&gt; <code>OnDockPanels()</code> (For Vault 2026+)</li>
<li><code>HiddenCommands()</code> =&gt; <code>OnHiddenCommands()</code></li>
</ul>
<pre><code class="lang-csharp">﻿<span class="hljs-keyword">using</span> Autodesk.Connectivity.Explorer.Extensibility;
<span class="hljs-keyword">using</span> System.ComponentModel;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedVaultAddin.Isolation</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;see cref="IExplorerExtension" /&gt;</span> is the entry point of the Vault addin.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    This class is extended to have fully isolated addin dependency container.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Inherit this class and add custom logic to overrides of <span class="hljs-doctag">&lt;see cref="Startup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="LogOn" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="LogOff" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="Shutdown" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="OnCommandSites" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="OnCustomEntityHandlers" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="OnDetailTabs" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="OnDockPanels" /&gt;</span>, or <span class="hljs-doctag">&lt;see cref="OnHiddenCommands" /&gt;</span>.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">IsolatedIExplorerExtension</span> : <span class="hljs-title">IExplorerExtension</span>
{
<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">object</span>? _isolatedInstance;
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Reference to the parameter in <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOn" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOff" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnShutdown" /&gt;</span>.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> IApplication Application { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">default</span>!;

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnStartup</span>(<span class="hljs-params">IApplication application</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnStartup), application);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Application = application;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        Startup();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            Startup();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnLogOn</span>(<span class="hljs-params">IApplication application</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnLogOn), application);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Application = application;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        LogOn();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            LogOn();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnLogOff</span>(<span class="hljs-params">IApplication application</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnLogOff), application);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Application = application;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        LogOff();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            LogOff();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnShutdown</span>(<span class="hljs-params">IApplication application</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnShutdown), application);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Application = application;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        Shutdown();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            Shutdown();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-keyword">public</span> IEnumerable&lt;CommandSite&gt;? CommandSites()
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke&lt;CommandSite&gt;(_isolatedInstance, <span class="hljs-keyword">nameof</span>(CommandSites));
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnCommandSites();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnCommandSites();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-keyword">public</span> IEnumerable&lt;CustomEntityHandler&gt;? CustomEntityHandlers()
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke&lt;CustomEntityHandler&gt;(_isolatedInstance, <span class="hljs-keyword">nameof</span>(CustomEntityHandlers));
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnCustomEntityHandlers();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnCustomEntityHandlers();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-keyword">public</span> IEnumerable&lt;DetailPaneTab&gt;? DetailTabs()
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke&lt;DetailPaneTab&gt;(_isolatedInstance, <span class="hljs-keyword">nameof</span>(DetailTabs));
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnDetailTabs();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnDetailTabs();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> VAULT_HAS_DOCK_PANELS</span>
    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-keyword">public</span> IEnumerable&lt;DockPanel&gt;? DockPanels()
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke&lt;DockPanel&gt;(_isolatedInstance, <span class="hljs-keyword">nameof</span>(DockPanels));
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnDockPanels();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnDockPanels();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-keyword">public</span> IEnumerable&lt;<span class="hljs-keyword">string</span>&gt;? HiddenCommands()
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke&lt;<span class="hljs-keyword">string</span>&gt;(_isolatedInstance, <span class="hljs-keyword">nameof</span>(HiddenCommands));
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnHiddenCommands();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnHiddenCommands();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin is loaded and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnStartup" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Startup</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault is logged into and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOn" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">LogOn</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault is logged out of and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOff" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">LogOff</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin is unloaded and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnShutdown" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Shutdown</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin ... and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.CommandSites" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> IEnumerable&lt;CommandSite&gt;? OnCommandSites();

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin ... and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.CustomEntityHandlers" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> IEnumerable&lt;CustomEntityHandler&gt;? OnCustomEntityHandlers();

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin ... and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.DetailTabs" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> IEnumerable&lt;DetailPaneTab&gt;? OnDetailTabs();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> VAULT_HAS_DOCK_PANELS</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin ... and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.DockPanels" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> IEnumerable&lt;DockPanel&gt;? OnDockPanels();
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span>    </span>

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin ... and <span class="hljs-doctag">&lt;see cref="IExplorerExtension.HiddenCommands" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> IEnumerable&lt;<span class="hljs-keyword">string</span>&gt;? OnHiddenCommands();
}
</code></pre>
<h3 id="heading-add-isolatediwebserviceextension-cs">Add <code>IsolatedIWebServiceExtension .cs</code></h3>
<p>This is used as the new entry point into the add-in. It is a wrapper around the <code>IWebServiceExtension</code>. It adds additional functionality behind the scenes but still exposes all methods called automatically by Vault.</p>
<ul>
<li><code>OnLoad()</code> =&gt; <code>Load()</code></li>
</ul>
<pre><code class="lang-csharp">﻿﻿<span class="hljs-keyword">using</span> Autodesk.Connectivity.WebServices;
<span class="hljs-keyword">using</span> System.ComponentModel;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedVaultAddin.Isolation</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;see cref="IWebServiceExtension" /&gt;</span> is the entry point of the Vault addin.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    This class is extended to have fully isolated addin dependency container.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Inherit this class and add custom logic to overrides of <span class="hljs-doctag">&lt;see cref="Load" /&gt;</span>.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">IsolatedIWebServiceExtension</span> : <span class="hljs-title">IWebServiceExtension</span>
{
<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">object</span>? _isolatedInstance;
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnLoad</span>(<span class="hljs-params"></span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnLoad));
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        Load();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            Load();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault addin is loaded and <span class="hljs-doctag">&lt;see cref="IWebServiceExtension.OnLoad" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Load</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<h3 id="heading-add-isolatedijobhandlercs">Add <code>IsolatedIJobHandler.cs</code></h3>
<p>This is used as the new entry point into the add-in. It is a wrapper around the <code>IJobHandler</code>. It adds additional functionality behind the scenes but still exposes all methods called automatically by Vault.</p>
<ul>
<li><code>Execute(IJobProcessorServices context, IJob job)</code> =&gt; <code>OnExecute()</code></li>
<li><code>CanProcess(string jobType)</code> =&gt; <code>OnCanProcess()</code></li>
<li><code>OnJobProcessorStartup(IJobProcessorServices context)</code> =&gt; <code>JobProcessorStartup()</code></li>
<li><code>OnJobProcessorShutdown(IJobProcessorServices context)</code> =&gt; <code>JobProcessorShutdown()</code></li>
<li><code>OnJobProcessorWake(IJobProcessorServices context)</code> =&gt; <code>JobProcessorWake()</code></li>
<li><code>OnJobProcessorSleep(IJobProcessorServices context)</code> =&gt; <code>JobProcessorSleep()</code></li>
</ul>
<pre><code class="lang-csharp">﻿﻿<span class="hljs-keyword">using</span> Autodesk.Connectivity.Explorer.Extensibility;
<span class="hljs-keyword">using</span> Autodesk.Connectivity.JobProcessor.Extensibility;
<span class="hljs-keyword">using</span> System.ComponentModel;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedVaultAddin.Isolation</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;see cref="IJobHandler" /&gt;</span> is the entry point of the Vault job processor addin.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    This class is extended to have fully isolated addin dependency container.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Inherit this class and add custom logic to overrides of <span class="hljs-doctag">&lt;see cref="OnExecute" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="OnCanProcess" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="JobProcessorStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="JobProcessorShutdown" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="JobProcessorWake" /&gt;</span>, or <span class="hljs-doctag">&lt;see cref="JobProcessorSleep" /&gt;</span>.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">IsolatedIJobHandler</span> : <span class="hljs-title">IJobHandler</span>
{
<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">object</span>? _isolatedInstance;
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Reference to the parameter in <span class="hljs-doctag">&lt;see cref="IExplorerExtension.Execute" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnJobProcessorStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnJobProcessorShutdown" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnJobProcessorWake" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnJobProcessorSleep" /&gt;</span>.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> IJobProcessorServices Context { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">default</span>!;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Reference to the parameter in <span class="hljs-doctag">&lt;see cref="IExplorerExtension.Execute" /&gt;</span>.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> IJob Job { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">default</span>!;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Reference to the parameter in <span class="hljs-doctag">&lt;see cref="IExplorerExtension.CanProcess" /&gt;</span>.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> JobType { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">default</span>!;

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]

    <span class="hljs-function"><span class="hljs-keyword">public</span> JobOutcome <span class="hljs-title">Execute</span>(<span class="hljs-params">IJobProcessorServices context, IJob job</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(Execute), context, job);
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Context = context;
        Job = job;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnExecute();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnExecute();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">CanProcess</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> jobType</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            <span class="hljs-keyword">return</span> AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(CanProcess), jobType);
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        JobType = jobType;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">return</span> OnCanProcess();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            <span class="hljs-keyword">return</span> OnCanProcess();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnJobProcessorStartup</span>(<span class="hljs-params">IJobProcessorServices context</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnJobProcessorStartup), context);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Context = context;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        JobProcessorStartup();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            JobProcessorStartup();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnJobProcessorShutdown</span>(<span class="hljs-params">IJobProcessorServices context</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnJobProcessorShutdown), context);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Context = context;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        JobProcessorShutdown();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            JobProcessorShutdown();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnJobProcessorWake</span>(<span class="hljs-params">IJobProcessorServices context</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnJobProcessorWake), context);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Context = context;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        JobProcessorWake();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            JobProcessorWake();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">EditorBrowsable(EditorBrowsableState.Never)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnJobProcessorSleep</span>(<span class="hljs-params">IJobProcessorServices context</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(OnJobProcessorSleep), context);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        Context = context;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        JobProcessorSleep();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            JobProcessorSleep();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault job processor is ... and <span class="hljs-doctag">&lt;see cref="IJobHandler.ExecuteAsync" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> JobOutcome <span class="hljs-title">OnExecute</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault job processor is ... and <span class="hljs-doctag">&lt;see cref="IJobHandler.CanProcess" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">OnCanProcess</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault job processor is ... and <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorStartup" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">JobProcessorStartup</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault job processor is ... and <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorShutdown" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">JobProcessorShutdown</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault job processor is ... and <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorWake" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">JobProcessorWake</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Vault job processor is ... and <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorSleep" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">JobProcessorSleep</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<h3 id="heading-add-addinloadcontextcs">Add <code>AddinLoadContext.cs</code></h3>
<p>This is a custom implementation of the <code>AssemblyLoadContext</code> specifically for the format of a Vault add-in.</p>
<pre><code class="lang-csharp">﻿<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
<span class="hljs-keyword">using</span> Autodesk.Connectivity.Explorer.Extensibility;
<span class="hljs-keyword">using</span> Autodesk.Connectivity.JobProcessor.Extensibility;
<span class="hljs-keyword">using</span> Autodesk.Connectivity.WebServices;
<span class="hljs-keyword">using</span> System.Reflection;
<span class="hljs-keyword">using</span> System.Runtime.Loader;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedVaultAddin.Isolation</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Isolated addin dependency container.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    References:</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support"&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Microsoft/Tutorials/Plugins</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;/a&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;a href="https://github.com/dotnet/coreclr/blob/v2.1.0/Documentation/design-docs/assemblyloadcontext.md"&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    GitHub/DotNet/CoreCLR</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;/a&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
<span class="hljs-keyword">internal</span> <span class="hljs-keyword">sealed</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AddinLoadContext</span> : <span class="hljs-title">AssemblyLoadContext</span>
{
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Add-ins contexts storage.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> Dictionary&lt;<span class="hljs-keyword">string</span>, AddinLoadContext&gt; _dependenciesProviders = <span class="hljs-keyword">new</span>(<span class="hljs-number">1</span>);

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> AssemblyDependencyResolver _resolver;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> BindingFlags MethodSearchFlags = BindingFlags.Public | BindingFlags.Instance;

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">AddinLoadContext</span>(<span class="hljs-params">Type type, <span class="hljs-keyword">string</span> addinName</span>) : <span class="hljs-title">base</span>(<span class="hljs-params">addinName</span>)</span>
    {
        <span class="hljs-keyword">string</span> addinLocation = type.Assembly.Location;

        _resolver = <span class="hljs-keyword">new</span> AssemblyDependencyResolver(addinLocation);
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Resolve and load dependency any time one is loaded if it exists in the isolated addin dependency container.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> Assembly? Load(AssemblyName assemblyName)
    {
        <span class="hljs-keyword">string</span>? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);

        <span class="hljs-keyword">return</span> assemblyPath <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span>
             ? LoadFromAssemblyPath(assemblyPath)
             : <span class="hljs-literal">null</span>;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Resolve and load unmanaged native dependency any time one is loaded if it exists in the isolated addin dependency container.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> nint <span class="hljs-title">LoadUnmanagedDll</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> assemblyName</span>)</span>
    {
        <span class="hljs-keyword">string</span>? assemblyPath = _resolver.ResolveUnmanagedDllToPath(assemblyName);

        <span class="hljs-keyword">return</span> assemblyPath <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span>
             ? LoadUnmanagedDllFromPath(assemblyPath)
             : nint.Zero;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Determine if the <span class="hljs-doctag">&lt;see cref="AssemblyLoadContext" /&gt;</span> is custom or still the default context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">CheckIfCustomContext</span>(<span class="hljs-params">Type type</span>)</span>
    {
        AssemblyLoadContext? currentContext = GetLoadContext(type.Assembly);

        <span class="hljs-keyword">return</span> currentContext != Default;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Get or create a new isolated context for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AddinLoadContext <span class="hljs-title">GetDependenciesProvider</span>(<span class="hljs-params">Type type</span>)</span>
    {
        <span class="hljs-comment">// Assembly location used as context name and the unique provider key.</span>
        <span class="hljs-keyword">string</span> addinRoot = System.IO.Path.GetDirectoryName(type.Assembly.Location)!;
        <span class="hljs-keyword">if</span> (_dependenciesProviders.TryGetValue(addinRoot, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> provider))
        {
            <span class="hljs-keyword">return</span> provider;
        }

        <span class="hljs-keyword">string</span> addinName = System.IO.Path.GetFileName(addinRoot);
        provider = <span class="hljs-keyword">new</span> AddinLoadContext(type, addinName);
        _dependenciesProviders.Add(addinRoot, provider);

        <span class="hljs-keyword">return</span> provider;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Create new instance in the separated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">object</span> <span class="hljs-title">CreateAssemblyInstance</span>(<span class="hljs-params">Type type</span>)</span>
    {
        <span class="hljs-keyword">string</span> assemblyLocation = type.Assembly.Location;
        Assembly assembly = LoadFromAssemblyPath(assemblyLocation);

        <span class="hljs-keyword">return</span> assembly.CreateInstance(type.FullName!)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Execute <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOn" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOff" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnShutdown" /&gt;</span> methods in the isolated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Matches parameter format of <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOn" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnLogOff" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IExplorerExtension.OnShutdown" /&gt;</span> methods.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName, IApplication application</span>)</span>
    {
        Type instanceType = instance.GetType();

        Type[] methodParameterTypes =
        [<span class="hljs-meta">
             typeof(IApplication)
        </span>];

        <span class="hljs-keyword">object</span>[] methodParameters =
        [<span class="hljs-meta">
             application
        </span>];

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, methodParameterTypes, <span class="hljs-literal">null</span>)!;

        _ = method.Invoke(instance, methodParameters)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Execute <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorShutdown" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorWake" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorSleep" /&gt;</span> methods in the isolated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Matches parameter format of <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorStartup" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorShutdown" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorWake" /&gt;</span>, <span class="hljs-doctag">&lt;see cref="IJobHandler.OnJobProcessorSleep" /&gt;</span> methods.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName, IJobProcessorServices context</span>)</span>
    {
        Type instanceType = instance.GetType();

        Type[] methodParameterTypes =
        [<span class="hljs-meta">
             typeof(IJobProcessorServices)
        </span>];

        <span class="hljs-keyword">object</span>[] methodParameters =
        [<span class="hljs-meta">
             context!
        </span>];

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, methodParameterTypes, <span class="hljs-literal">null</span>)!;

        _ = method.Invoke(instance, methodParameters)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Execute <span class="hljs-doctag">&lt;see cref="IJobHandler.Execute" /&gt;</span> method in the isolated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Matches parameter format of <span class="hljs-doctag">&lt;see cref="IJobHandler.Execute" /&gt;</span> method.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> JobOutcome <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName, IJobProcessorServices context, IJob job</span>)</span>
    {
        Type instanceType = instance.GetType();

        Type[] methodParameterTypes =
        [<span class="hljs-meta">
             typeof(IJobProcessorServices),
             typeof(IJob)
        </span>];

        <span class="hljs-keyword">object</span>[] methodParameters =
        [<span class="hljs-meta">
             context!,
             job!
        </span>];

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, methodParameterTypes, <span class="hljs-literal">null</span>)!;

        <span class="hljs-keyword">return</span> (JobOutcome)method.Invoke(instance, methodParameters)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Execute <span class="hljs-doctag">&lt;see cref="IJobHandler.CanProcess" /&gt;</span> method in the isolated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Matches parameter format of <span class="hljs-doctag">&lt;see cref="IJobHandler.CanProcess" /&gt;</span> method.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName, <span class="hljs-keyword">string</span> jobType</span>)</span>
    {
        Type instanceType = instance.GetType();

        Type[] methodParameterTypes =
        [<span class="hljs-meta">
             typeof(string)
        </span>];

        <span class="hljs-keyword">object</span>[] methodParameters =
        [<span class="hljs-meta">
             jobType
        </span>];

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, methodParameterTypes, <span class="hljs-literal">null</span>)!;

        <span class="hljs-keyword">return</span> (<span class="hljs-keyword">bool</span>)method.Invoke(instance, methodParameters)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Execute <span class="hljs-doctag">&lt;see cref="IWebServiceExtension.OnLoad" /&gt;</span> method in the isolated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Matches parameter format of <span class="hljs-doctag">&lt;see cref="IWebServiceExtension.OnLoad" /&gt;</span> method.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName</span>)</span>
    {
        Type instanceType = instance.GetType();

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, [], <span class="hljs-literal">null</span>)!;

        _ = method.Invoke(instance, [])!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Execute <span class="hljs-doctag">&lt;see cref="IExplorerExtension.CommandSites" /&gt;</span> method in the isolated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Matches parameter format of <span class="hljs-doctag">&lt;see cref="IExplorerExtension.CommandSites" /&gt;</span> method.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-title">IEnumerable</span>&lt;<span class="hljs-title">T</span>&gt;? <span class="hljs-title">Invoke</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName</span>)</span>
    {
        Type instanceType = instance.GetType();

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, [], <span class="hljs-literal">null</span>)!;

        <span class="hljs-keyword">return</span> (IEnumerable&lt;T&gt;?)method.Invoke(instance, [])!;
    }
}
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
</code></pre>
<h3 id="heading-add-resolvehelpercs">Add <code>ResolveHelper.cs</code></h3>
<p>This is a helper class used to resolve conflicting versions of a dependency.</p>
<pre><code class="lang-csharp">﻿<span class="hljs-keyword">using</span> System.Reflection;
<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
<span class="hljs-keyword">using</span> System.Runtime.Loader;
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedVaultAddin.Isolation</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Used to resolve conflicting versions of a dependency.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ResolveHelper</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span>? _moduleDirectory;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">object</span>? _domainResolvers;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Subscribes the current domain to resolve dependencies for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;typeparam name="T"&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Type, to search for dependencies in the directory where this type is defined.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/typeparam&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Dependencies are searched in a directory of the specified type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    At the time of dependency resolution, all other dependency resolution methods for the domain are disabled,</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    this requires calling <span class="hljs-doctag">&lt;see cref="EndAssemblyResolve" /&gt;</span> immediately after executing user code where dependency failures occur.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">BeginAssemblyResolve</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params"></span>)</span>
    {
        BeginAssemblyResolve(<span class="hljs-keyword">typeof</span>(T));
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Subscribes the current domain to resolve dependencies for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="type"&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Type, to search for dependencies in the directory where this type is defined.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/param&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Dependencies are searched in a directory of the specified type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    At the time of dependency resolution, all other dependency resolution methods for the domain are disabled,</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    this requires calling <span class="hljs-doctag">&lt;see cref="EndAssemblyResolve" /&gt;</span> immediately after executing user code where dependency failures occur.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">BeginAssemblyResolve</span>(<span class="hljs-params">Type type</span>)</span>
    {
        <span class="hljs-keyword">if</span> (_domainResolvers <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span>)
            <span class="hljs-keyword">return</span>;
        <span class="hljs-keyword">if</span> (type.Module.FullyQualifiedName == <span class="hljs-string">"&lt;Unknown&gt;"</span>)
            <span class="hljs-keyword">return</span>;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">var</span> loadContextType = <span class="hljs-keyword">typeof</span>(AssemblyLoadContext);
        <span class="hljs-keyword">var</span> resolversField = loadContextType.GetField(<span class="hljs-string">"AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly)!;
        <span class="hljs-keyword">var</span> resolvers = resolversField.GetValue(<span class="hljs-literal">null</span>);
        resolversField.SetValue(<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>);
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">var</span> domainType = AppDomain.CurrentDomain.GetType();
        <span class="hljs-keyword">var</span> resolversField = domainType.GetField(<span class="hljs-string">"_AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)!;
        <span class="hljs-keyword">var</span> resolvers = resolversField.GetValue(AppDomain.CurrentDomain);
        resolversField.SetValue(AppDomain.CurrentDomain, <span class="hljs-literal">null</span>);
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        _domainResolvers = resolvers;
        _moduleDirectory = System.IO.Path.GetDirectoryName(type.Module.FullyQualifiedName);

        AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Unsubscribes the current domain to resolve dependencies for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">EndAssemblyResolve</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (_domainResolvers <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)
            <span class="hljs-keyword">return</span>;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">var</span> loadContextType = <span class="hljs-keyword">typeof</span>(AssemblyLoadContext);
        <span class="hljs-keyword">var</span> resolversField = loadContextType.GetField(<span class="hljs-string">"AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly)!;
        resolversField.SetValue(<span class="hljs-literal">null</span>, _domainResolvers);
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">var</span> domainType = AppDomain.CurrentDomain.GetType();
        <span class="hljs-keyword">var</span> resolversField = domainType.GetField(<span class="hljs-string">"_AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)!;
        resolversField.SetValue(AppDomain.CurrentDomain, _domainResolvers);
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        _domainResolvers = <span class="hljs-literal">null</span>;
        _moduleDirectory = <span class="hljs-literal">null</span>;

        AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve;
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Assembly? OnAssemblyResolve(<span class="hljs-keyword">object</span>? sender, ResolveEventArgs args)
    {
        <span class="hljs-keyword">string</span>? assemblyName = <span class="hljs-keyword">new</span> AssemblyName(args.Name).Name;

        <span class="hljs-keyword">string</span> assemblyPath = System.IO.Path.Combine(_moduleDirectory!, <span class="hljs-string">$"<span class="hljs-subst">{assemblyName}</span>.dll"</span>);
        <span class="hljs-keyword">if</span> (System.IO.File.Exists(assemblyPath) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;

        <span class="hljs-keyword">return</span> Assembly.LoadFrom(assemblyPath);
    }
}
</code></pre>
<h3 id="heading-update-project-csproj-file">Update Project (.csproj) File</h3>
<ul>
<li>Must set <code>Private</code> to <code>False</code> on Vault-related assembly file reference.</li>
<li>Replace <code>VaultVersion</code> value of <code>2026</code> with the version of Vault being referenced.</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- Custom Variable --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">VaultVersion</span>&gt;</span>2026<span class="hljs-tag">&lt;/<span class="hljs-name">VaultVersion</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span> <span class="hljs-attr">Condition</span>=<span class="hljs-string">"$(VaultVersion) &gt;= 2026"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">DefineConstants</span>&gt;</span>$(DefineConstants);VAULT_HAS_DOCK_PANELS<span class="hljs-tag">&lt;/<span class="hljs-name">DefineConstants</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.Connectivity.Explorer.Extensibility"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Vault Client $(VaultVersion)\Explorer\Autodesk.Connectivity.Explorer.Extensibility.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.Connectivity.Extensibility.Framework"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Vault Client $(VaultVersion)\Explorer\Autodesk.Connectivity.Extensibility.Framework.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.Connectivity.JobProcessor.Extensibility"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Vault Client $(VaultVersion)\Explorer\Autodesk.Connectivity.JobProcessor.Extensibility.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.Connectivity.WebServices"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Vault Client $(VaultVersion)\Explorer\Autodesk.Connectivity.WebServices.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.DataManagement.Client.Framework"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Vault Client $(VaultVersion)\Explorer\Autodesk.DataManagement.Client.Framework.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.DataManagement.Client.Framework.Vault"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Vault Client $(VaultVersion)\Explorer\Autodesk.DataManagement.Client.Framework.Vault.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>
</code></pre>
<h2 id="heading-notes">Notes</h2>
<ul>
<li>This add-in format is compatible with Vault versions using .NET Framework 4.8 or .NET 8.</li>
</ul>
<h2 id="heading-references">References</h2>
<ul>
<li>Microsoft Learn - <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext">System.Runtime.Loader.AssemblyLoadContext</a></li>
<li>GitHub - dotnet - <a target="_blank" href="https://github.com/dotnet/coreclr/blob/v2.1.0/Documentation/design-docs/assemblyloadcontext.md">AssemblyLoadContext.md</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Using Visual Studio to Debug iLogic Rules]]></title><description><![CDATA[Visual Studio can be used to debug Autodesk Inventor iLogic rules, both internal and external, by attaching to the running Inventor process and triggering breakpoints in the rule code. This guide outlines a workflow for step-through debugging and var...]]></description><link>https://tylerwarner.dev/using-visual-studio-to-debug-ilogic-rules</link><guid isPermaLink="true">https://tylerwarner.dev/using-visual-studio-to-debug-ilogic-rules</guid><category><![CDATA[autodesk ]]></category><dc:creator><![CDATA[Tyler Warner]]></dc:creator><pubDate>Mon, 22 Dec 2025 12:00:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/gTs2w7bu3Qo/upload/2d5c586939ee1bb6da40254aaa4532a3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Visual Studio can be used to debug Autodesk Inventor iLogic rules, both internal and external, by attaching to the running Inventor process and triggering breakpoints in the rule code. This guide outlines a workflow for step-through debugging and variable inspection of iLogic rules.</p>
<h2 id="heading-core-concepts">Core Concepts</h2>
<ul>
<li>iLogic rules execute inside the Inventor process.</li>
<li>Visual Studio must attach to Inventor after it is already running.</li>
<li>Breakpoints are triggered programmatically from within the rule, not pre-set in source files.</li>
<li>Visual Studio opens a read-only temporary, runtime-generated file for debugging.</li>
</ul>
<h2 id="heading-attaching-visual-studio-to-inventor">Attaching Visual Studio to Inventor</h2>
<h3 id="heading-step-by-step">Step-By-Step</h3>
<ul>
<li>Launch <code>Autodesk Inventor</code>.</li>
<li>Open <code>Visual Studio</code>, with or without code.</li>
<li>In <code>Visual Studio</code>:<ul>
<li>Navigate to <code>Debug</code> =&gt; <code>Attach To Process</code></li>
<li>Set:<ul>
<li>Connection Type: <code>Local</code></li>
<li>Process: <code>Inventor.exe</code></li>
</ul>
</li>
<li>Click <code>Attach</code></li>
</ul>
</li>
</ul>
<h3 id="heading-expected-result">Expected Result</h3>
<ul>
<li>Visual Studio is now listening to the Inventor process.</li>
<li>No source code opens yet.</li>
<li>Visual Studio will activate only when a breakpoint or exception is hit.</li>
</ul>
<p>For Autodesk's official walkthrough, see:
<a target="_blank" href="https://blog.autodesk.io/using-visual-studio-to-debug-ilogic-rules/">Using Visual Studio to Debug iLogic Rules</a></p>
<hr />
<h2 id="heading-debugging-ilogic-rules">Debugging iLogic Rules</h2>
<h3 id="heading-how-it-works">How It Works</h3>
<ul>
<li>Inventor signals the debugger when execution reaches the breakpoint call.</li>
<li>Visual Studio opens a temporary runtime version of the rule.</li>
<li>Execution pauses on the break line.</li>
<li>All local variables, objects, and the call stack are inspectable.</li>
</ul>
<h3 id="heading-internal-ilogic-rules">Internal iLogic Rules</h3>
<p>Internal iLogic rules have a built-in keyword that acts as a breakpoint and triggers a pause in the execution.</p>
<p>Add the following line anywhere in the rule:</p>
<pre><code class="lang-vb">Break()
</code></pre>
<h3 id="heading-external-ilogic-rules">External iLogic Rules</h3>
<p>External rules can have a similar method for the same functionality as the internal rules. These rules are compiled at runtime, allowing changes to take effect immediately without restarting Inventor.</p>
<p>Add the following method to the external rule class and call it anywhere in the rule:</p>
<pre><code class="lang-vb">''' &lt;summary&gt;
''' Allow external debugger to attach like a breakpoint.
''' &lt;/summary&gt;
''' &lt;remarks&gt;
''' &lt;see cref="System.Diagnostics.DebuggerStepThroughAttribute"/&gt; attribute prevents stepping into the helper method itself.
''' &lt;/remarks&gt;
&lt;System.Diagnostics.DebuggerStepThrough&gt;
Public Shared Sub Break()
    If System.Diagnostics.Debugger.IsAttached Then
        System.Diagnostics.Debugger.Break()
    End If
End Sub
</code></pre>
<hr />
<h2 id="heading-resetting-the-ilogic-cache">Resetting The iLogic Cache</h2>
<p>iLogic can cache rules and store runtime state. The following command, which can be added to a separate rule, will force iLogic to release memory and reset its execution context.</p>
<h3 id="heading-usage-when-to-consider-resetting">Usage (When to Consider Resetting)</h3>
<ul>
<li>Inconsistent internal rule behavior.</li>
<li>Long debugging sessions.<pre><code class="lang-vb">ThisApplication.CommandManager.ControlDefinitions.OfType(Of ControlDefinition)() _
  .FirstOrDefault(Function(c) c.InternalName = "iLogic.FreeILogicMemory") _
  ?.Execute()
</code></pre>
</li>
</ul>
<h2 id="heading-common-pitfalls">Common Pitfalls</h2>
<ul>
<li>Forgetting to attach before executing the rules.</li>
<li>Expecting breakpoints to persist between runs.</li>
<li>Editing the temporary files opened by Visual Studio.</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>With a simple attach-to-process setup and deliberate breakpoint triggers, Visual Studio becomes a powerful debugging environment for iLogic development. This approach scales from quick rule inspection to larger external rule workflows and provides a consistent debugging experience for Inventor automation.</p>
]]></content:encoded></item><item><title><![CDATA[How to Use AssemblyLoadContext for Isolating Inventor Addin Dependencies]]></title><description><![CDATA[Autodesk Inventor previously allowed add-ins to use NuGet package/assembly versions that differ from the ones bundled with Inventor. However, with Autodesk Inventor 2025 and the framework upgrade to .NET 8, this no longer worked out of the box and ca...]]></description><link>https://tylerwarner.dev/assemblyloadcontext-for-inventor-addins</link><guid isPermaLink="true">https://tylerwarner.dev/assemblyloadcontext-for-inventor-addins</guid><category><![CDATA[Autodesk Inventor]]></category><dc:creator><![CDATA[Tyler Warner]]></dc:creator><pubDate>Wed, 29 Oct 2025 11:24:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/9cCeS9Sg6nU/upload/4ad55992bb1191deb81cf9e1affffa54.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Autodesk Inventor previously allowed add-ins to use NuGet package/assembly versions that differ from the ones bundled with Inventor. However, with Autodesk Inventor 2025 and the framework upgrade to .NET 8, this no longer worked out of the box and caused version conflicts.</p>
<p>This article will demonstrate one way to resolve the version conflict by isolating the add-in’s dependencies in a separate container using <code>AssemblyLoadContext</code>.</p>
<p>A <a target="_blank" href="https://github.com/tylerwarner33/autodesk-inventor-assembly-load-context">full sample application</a> can be found on GitHub.</p>
<h2 id="heading-what-is-assemblyloadcontexthttpslearnmicrosoftcomen-usdotnetcoredependency-loadingunderstanding-assemblyloadcontext">What is <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext">AssemblyLoadContext</a>?</h2>
<blockquote>
<ul>
<li>It's the runtime's provider for locating and loading dependencies. Whenever a dependency is loaded, an AssemblyLoadContext instance is invoked to locate it.</li>
<li>AssemblyLoadContext provides a service of locating, loading, and caching managed assemblies and other dependencies.</li>
<li>To support dynamic code loading and unloading, it creates an isolated context for loading code and its dependencies in their own AssemblyLoadContext instance.</li>
</ul>
</blockquote>
<h2 id="heading-how-to-update-the-add-in">How to update the add-in?</h2>
<h3 id="heading-add-isolatedapplicationaddinservercs">Add <code>IsolatedApplicationAddInServer.cs</code></h3>
<p>This is used as the new entry point into the add-in. It is a wrapper around the <a target="_blank" href="https://help.autodesk.com/view/INVNTOR/2025/ENU/?guid=GUID-ApplicationAddInServer">ApplicationAddInServer</a>. It adds additional functionality behind the scenes but still exposes the startup and shutdown methods called automatically by Inventor.</p>
<ul>
<li><code>Activate(ApplicationAddInSite application, bool firstTime)</code> =&gt; <code>OnActivate()</code></li>
<li><code>Deactivate()</code> =&gt; <code>OnDeactivate()</code></li>
</ul>
<pre><code class="lang-csharp">﻿<span class="hljs-keyword">using</span> Inventor;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedInventorAddin</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer" /&gt;</span> is the standard entry point of the Inventor addin.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    This class is extended to have fully isolated addin dependency container.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Inherit this class and add custom logic to overrides of <span class="hljs-doctag">&lt;see cref="OnActivate" /&gt;</span> or <span class="hljs-doctag">&lt;see cref="OnDeactivate" /&gt;</span>.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">IsolatedApplicationAddInServer</span> : <span class="hljs-title">ApplicationAddInServer</span>
{
<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">object</span>? _isolatedInstance;
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">object</span>? Automation { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-literal">null</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Reference to the parameter in <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer.Activate" /&gt;</span>.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> ApplicationAddInSite ApplicationAddInSite { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">default</span>!;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Reference to the parameter in <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer.Activate" /&gt;</span>.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> FirstTime { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">default</span>!;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Activate</span>(<span class="hljs-params">ApplicationAddInSite applicationAddInSite, <span class="hljs-keyword">bool</span> firstTime</span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext dependenciesProvider = AddinLoadContext.GetDependenciesProvider(currentType);
            _isolatedInstance = dependenciesProvider.CreateAssemblyInstance(currentType);

            AddinLoadContext.Invoke(_isolatedInstance, <span class="hljs-keyword">nameof</span>(Activate), applicationAddInSite, firstTime);
            <span class="hljs-keyword">return</span>;
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        ApplicationAddInSite = applicationAddInSite;
        FirstTime = firstTime;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        OnActivate();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            OnActivate();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deactivate</span>(<span class="hljs-params"></span>)</span>
    {
        Type currentType = GetType();

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">if</span> (AddinLoadContext.CheckIfCustomContext(currentType) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
        {
            AddinLoadContext.Invoke(_isolatedInstance!, <span class="hljs-keyword">nameof</span>(Deactivate));
            <span class="hljs-keyword">return</span>;
        }

        OnDeactivate();
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">try</span>
        {
            ResolveHelper.BeginAssemblyResolve(currentType);
            OnDeactivate();
        }
        <span class="hljs-keyword">finally</span>
        {
            ResolveHelper.EndAssemblyResolve();
        }
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
    }

    [<span class="hljs-meta">Obsolete(<span class="hljs-meta-string">"Deprecated in the Inventor API. Required for legacy compatibility."</span>)</span>]
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ExecuteCommand</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> CommandID</span>)</span> { }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Inventor addin is loaded and <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer.Activate" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnActivate</span>(<span class="hljs-params"></span>)</span>;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Overload this method to execute custom logic when the Inventor addin is unloaded and <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer.Deactivate" /&gt;</span> method is executed.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnDeactivate</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<h3 id="heading-add-addinloadcontextcs">Add <code>AddinLoadContext.cs</code></h3>
<p>This is a custom implementation of the <code>AssemblyLoadContext</code> specifically for the format of an Inventor add-in.</p>
<pre><code class="lang-csharp">﻿<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
<span class="hljs-keyword">using</span> Inventor;
<span class="hljs-keyword">using</span> System.Reflection;
<span class="hljs-keyword">using</span> System.Runtime.Loader;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedInventorAddin</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>     Isolated add-in dependency container.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">internal</span> <span class="hljs-keyword">sealed</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AddinLoadContext</span> : <span class="hljs-title">AssemblyLoadContext</span>
{
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Add-ins contexts storage.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> Dictionary&lt;<span class="hljs-keyword">string</span>, AddinLoadContext&gt; _dependenciesProviders = <span class="hljs-keyword">new</span>(<span class="hljs-number">1</span>);
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> AssemblyDependencyResolver _resolver;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> BindingFlags MethodSearchFlags = BindingFlags.Public | BindingFlags.Instance;

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">AddinLoadContext</span>(<span class="hljs-params">Type type, <span class="hljs-keyword">string</span> addinName</span>) : <span class="hljs-title">base</span>(<span class="hljs-params">addinName</span>)</span>
    {
        <span class="hljs-keyword">string</span> addinLocation = type.Assembly.Location;
        _resolver = <span class="hljs-keyword">new</span> AssemblyDependencyResolver(addinLocation);
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Resolve dependency any time one is loaded if it exists in the isolated add-in dependency container.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> Assembly? Load(AssemblyName assemblyName)
    {
        <span class="hljs-keyword">string</span>? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
        <span class="hljs-keyword">return</span> assemblyPath <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span> ? LoadFromAssemblyPath(assemblyPath) : <span class="hljs-literal">null</span>;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Determine whether the type is the type not associated with the default context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">CheckAccess</span>(<span class="hljs-params">Type type</span>)</span>
    {
        AssemblyLoadContext? currentContext = GetLoadContext(type.Assembly);
        <span class="hljs-keyword">return</span> currentContext != Default;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Get or create a new isolated context for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AddinLoadContext <span class="hljs-title">GetDependenciesProvider</span>(<span class="hljs-params">Type type</span>)</span>
    {
        <span class="hljs-comment">// Assembly location used as context name and the unique provider key.</span>
        <span class="hljs-keyword">string</span> addinRoot = System.IO.Path.GetDirectoryName(type.Assembly.Location)!;
        <span class="hljs-keyword">if</span> (_dependenciesProviders.TryGetValue(addinRoot, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> provider))
        {
            <span class="hljs-keyword">return</span> provider;
        }

        <span class="hljs-keyword">string</span> addinName = System.IO.Path.GetFileName(addinRoot);
        provider = <span class="hljs-keyword">new</span> AddinLoadContext(type, addinName);
        _dependenciesProviders.Add(addinRoot, provider);
        <span class="hljs-keyword">return</span> provider;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Create new instance in the separated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">object</span> <span class="hljs-title">CreateInstance</span>(<span class="hljs-params">Type type</span>)</span>
    {
        <span class="hljs-keyword">string</span> assemblyLocation = type.Assembly.Location;
        Assembly assembly = LoadFromAssemblyPath(assemblyLocation);
        <span class="hljs-keyword">return</span> assembly.CreateInstance(type.FullName!)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Execute <span class="hljs-doctag">&lt;see cref="ApplicationAddInSite" /&gt;</span> in the separated context.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Matches parameter format of <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer.Activate" /&gt;</span> method.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName, ApplicationAddInSite application, <span class="hljs-keyword">bool</span> firstTime</span>)</span>
    {
        Type instanceType = instance.GetType();
        Type[] methodParameterTypes =
        [<span class="hljs-meta">
            typeof(ApplicationAddInSite),
            typeof(bool)
        </span>];
        <span class="hljs-keyword">object</span>[] methodParameters =
        [<span class="hljs-meta">
            application,
            firstTime
        </span>];

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, methodParameterTypes, <span class="hljs-literal">null</span>)!;
        <span class="hljs-comment">// Call the inheriting method which may contain custom logic if it exists.</span>
        _ = method.Invoke(instance, methodParameters)!;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>     Matches parameter format of <span class="hljs-doctag">&lt;see cref="ApplicationAddInServer.Deactivate" /&gt;</span> method.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Invoke</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> instance, <span class="hljs-keyword">string</span> methodName</span>)</span>
    {
        Type instanceType = instance.GetType();

        MethodInfo method = instanceType.GetMethod(methodName, MethodSearchFlags, <span class="hljs-literal">null</span>, [], <span class="hljs-literal">null</span>)!;
        <span class="hljs-comment">// Call the inheriting method which may contain custom logic if it exists.</span>
        _ = method.Invoke(instance, [])!;
    }
}
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>
</code></pre>
<h3 id="heading-add-resolvehelpercs">Add <code>ResolveHelper.cs</code></h3>
<p>This is a helper class used to resolve conflicting versions of a dependency.</p>
<pre><code class="lang-csharp"><span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
<span class="hljs-keyword">using</span> System.Runtime.Loader;
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">IsolatedInventorAddin</span>;

<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span>    Used to resolve conflicting versions of a dependency.</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ResolveHelper</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">string</span>? _moduleDirectory;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">object</span>? _domainResolvers;

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>   Subscribes the current domain to resolve dependencies for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;typeparam name="T"&gt;</span>Type, to search for dependencies in the directory where this type is defined.<span class="hljs-doctag">&lt;/typeparam&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Dependencies are searched in a directory of the specified type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    At the time of dependency resolution, all other dependency resolution methods for the domain are disabled,</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    this requires calling <span class="hljs-doctag">&lt;see cref="EndAssemblyResolve" /&gt;</span> immediately after executing user code where dependency failures occur.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">BeginAssemblyResolve</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params"></span>)</span>
    {
        BeginAssemblyResolve(<span class="hljs-keyword">typeof</span>(T));
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Subscribes the current domain to resolve dependencies for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="type"&gt;</span>Type, to search for dependencies in the directory where this type is defined.<span class="hljs-doctag">&lt;/param&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;remarks&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Dependencies are searched in a directory of the specified type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    At the time of dependency resolution, all other dependency resolution methods for the domain are disabled,</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    this requires calling <span class="hljs-doctag">&lt;see cref="EndAssemblyResolve" /&gt;</span> immediately after executing user code where dependency failures occur.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/remarks&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">BeginAssemblyResolve</span>(<span class="hljs-params">Type type</span>)</span>
    {
        <span class="hljs-keyword">if</span> (_domainResolvers <span class="hljs-keyword">is</span> not <span class="hljs-literal">null</span>)
            <span class="hljs-keyword">return</span>;
        <span class="hljs-keyword">if</span> (type.Module.FullyQualifiedName == <span class="hljs-string">"&lt;Unknown&gt;"</span>)
            <span class="hljs-keyword">return</span>;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">var</span> loadContextType = <span class="hljs-keyword">typeof</span>(AssemblyLoadContext);
        <span class="hljs-keyword">var</span> resolversField = loadContextType.GetField(<span class="hljs-string">"AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly)!;
        <span class="hljs-keyword">var</span> resolvers = resolversField.GetValue(<span class="hljs-literal">null</span>);
        resolversField.SetValue(<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>);
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">var</span> domainType = AppDomain.CurrentDomain.GetType();
        <span class="hljs-keyword">var</span> resolversField = domainType.GetField(<span class="hljs-string">"_AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)!;
        <span class="hljs-keyword">var</span> resolvers = resolversField.GetValue(AppDomain.CurrentDomain);
        resolversField.SetValue(AppDomain.CurrentDomain, <span class="hljs-literal">null</span>);
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        _domainResolvers = resolvers;
        _moduleDirectory = System.IO.Path.GetDirectoryName(type.Module.FullyQualifiedName);

        AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
    }

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span>    Unsubscribes the current domain to resolve dependencies for the type.</span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">EndAssemblyResolve</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (_domainResolvers <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)
            <span class="hljs-keyword">return</span>;

<span class="hljs-meta">#<span class="hljs-meta-keyword">if</span> NETCOREAPP</span>
        <span class="hljs-keyword">var</span> loadContextType = <span class="hljs-keyword">typeof</span>(AssemblyLoadContext);
        <span class="hljs-keyword">var</span> resolversField = loadContextType.GetField(<span class="hljs-string">"AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly)!;
        resolversField.SetValue(<span class="hljs-literal">null</span>, _domainResolvers);
<span class="hljs-meta">#<span class="hljs-meta-keyword">else</span></span>
        <span class="hljs-keyword">var</span> domainType = AppDomain.CurrentDomain.GetType();
        <span class="hljs-keyword">var</span> resolversField = domainType.GetField(<span class="hljs-string">"_AssemblyResolve"</span>, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)!;
        resolversField.SetValue(AppDomain.CurrentDomain, _domainResolvers);
<span class="hljs-meta">#<span class="hljs-meta-keyword">endif</span></span>

        _domainResolvers = <span class="hljs-literal">null</span>;
        _moduleDirectory = <span class="hljs-literal">null</span>;

        AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve;
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Assembly? OnAssemblyResolve(<span class="hljs-keyword">object</span>? sender, ResolveEventArgs args)
    {
        <span class="hljs-keyword">string</span> assemblyName = <span class="hljs-keyword">new</span> AssemblyName(args.Name).Name;

        <span class="hljs-keyword">var</span> assemblyPath = System.IO.Path.Combine(_moduleDirectory!, <span class="hljs-string">$"<span class="hljs-subst">{assemblyName}</span>.dll"</span>);
        <span class="hljs-keyword">if</span> (System.IO.File.Exists(assemblyPath) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;

        <span class="hljs-keyword">return</span> Assembly.LoadFrom(assemblyPath);
    }
}
</code></pre>
<h3 id="heading-update-project-csproj-file">Update Project (.csproj) File</h3>
<ul>
<li>Must set <code>Private</code> to <code>False</code> on <code>Autodesk.Inventor.Interop</code> assembly file reference.</li>
<li>Replace <code>2026</code> with the version of Inventor being referenced.</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- Custom Variable --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">InventorVersion</span>&gt;</span>2026<span class="hljs-tag">&lt;/<span class="hljs-name">InventorVersion</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Reference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Autodesk.Inventor.Interop"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">HintPath</span>&gt;</span>$(ProgramFiles)\Autodesk\Inventor $(InventorVersion)\Bin\Public Assemblies\Autodesk.Inventor.Interop.dll<span class="hljs-tag">&lt;/<span class="hljs-name">HintPath</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Required For Isolated Addin --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Private</span>&gt;</span>False<span class="hljs-tag">&lt;/<span class="hljs-name">Private</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Reference</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>
</code></pre>
<h2 id="heading-notes">Notes</h2>
<ul>
<li>This add-in format is compatible with Inventor versions using .NET Framework 4.8 or .NET 8.</li>
<li>This add-in format is compatible and works as an <code>AppBundle</code> with the <a target="_blank" href="https://aps.autodesk.com/en/docs/design-automation/v3/developers_guide/overview/">Automation API</a>.</li>
</ul>
<h2 id="heading-references">References</h2>
<ul>
<li>Microsoft Learn - <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext">System.Runtime.Loader.AssemblyLoadContext</a></li>
<li>GitHub - dotnet - <a target="_blank" href="https://github.com/dotnet/coreclr/blob/v2.1.0/Documentation/design-docs/assemblyloadcontext.md">AssemblyLoadContext.md</a></li>
</ul>
]]></content:encoded></item></channel></rss>