VSTO Add-ins fail to load: ComponentAppInfo conflict when multiple add-ins share domain-neutral assemblies
Problem Description
When multiple VSTO add-ins (CopyPaste, ExcelFormulas) are installed in the same Office application (Excel), only one add-in loads successfully. The second add-in fails with error:
ComponentAppInfo must be set before resolving dependencies!
Call 'FutureDependencyInjector.ComponentAppInfo = typeof(YourInfoProvider)'
in ThisAddIn_Startup() before any Resolve() calls.
Root Cause Analysis
Initial Hypothesis
Each VSTO add-in runs in its own AppDomain, so static variables should be isolated.
Actual Root Cause (Confirmed via Fusion Logs)
- ExcelFormulas loads in AppDomain ID: 2
- CopyPaste loads in AppDomain ID: 3
However, both add-ins reference SVI.AppraisalData.dll from the same location:
C:\Program Files\Southland Valuation Incorporated\SVI AddIn\
When .NET loads an assembly as domain-neutral (shared across AppDomains for performance), static fields are shared between AppDomains!
Sequence of Failure
- ExcelFormulas (Domain 2) loads → sets
FutureDependencyInjector.ComponentAppInfo - CopyPaste (Domain 3) loads → tries to set
ComponentAppInfo→ FAILS (already set in shared memory)
Solution
Replace static fields with per-AppDomain storage using AppDomain.CurrentDomain.SetData/GetData:
// Before (shared across AppDomains when assembly is domain-neutral)
private static Type _componentAppInfo;
// After (isolated per AppDomain)
private const string AppDomainKey_ComponentAppInfo = "FutureDependencyInjector.ComponentAppInfo";
public static Type ComponentAppInfo
{
get => AppDomain.CurrentDomain.GetData(AppDomainKey_ComponentAppInfo) as Type;
set => AppDomain.CurrentDomain.SetData(AppDomainKey_ComponentAppInfo, value);
}
Same pattern applied to:
_staticContainer(Lazy<IContainer>)_pendingModules(List<Action<ContainerBuilder>>)_componentAppInfo(Type)
Additional Fixes Required
1. WiX Installer Registry (64-bit Office)
Add Bitness="always64" to HKLM registry components to ensure they write to native registry (not WOW6432Node) when building x86 MSI:
<Component Id="Reg_CopyPaste_HKLM" Guid="*" Bitness="always64">
2. Registry Cleanup (Legacy Entries)
Old installer used different registry key names. Add cleanup to remove duplicates:
<RemoveRegistryKey Root="HKCU" Key="Software\Microsoft\Office\Excel\Addins\CopyPaste" Action="removeOnInstall" />
<RemoveRegistryKey Root="HKCU" Key="Software\Microsoft\Office\Excel\Addins\ExcelFormulas" Action="removeOnInstall" />
3. Solution Configuration Mapping
WiX projects don't support Any CPU - map to x86:
{GUID}.Debug|Any CPU.ActiveCfg = Debug|x86
{GUID}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
Files Changed
src/AppraisalData/IoC/FutureDependencyInjector.cs- Per-AppDomain storagesrc/setup/Installer/Components.wxs- Bitness + registry cleanupsrc/SVI.sln- WiX project configuration mapping
Testing
- Build all add-in projects
- Open Excel
- Verify both CopyPaste and ExcelFormulas ribbons appear
- Check logs:
C:\SVI\logs\admin\should have separate log files for each add-in
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗