I’ve got a situation where an application uses a plugin model to load assemblies at runtime. Most of these assemblies have a further dependency on a common assembly which is modified over time.
For example, Plugin A depends on Version 1 of Common and Plugin B depends on Version 2 of Common.
The plugins are self contained and the common assemblies are strongly named, so in a purely managed environment the different Common assemblies get loaded and there’s no danger of an accidental cast between types from the different Common versions and everything works fine.
When loading from a mixed-mode assembly, which is a requirement, we are in a situation where the first loaded assembly ‘wins’. So in the example, Plugin B would attempt to load against Common v1 that in our case throws a TypeLoadException because of some missing types in the old version of the assembly.
How can we force the C++/CLI environment to honor the verisoning of the reference in the plugins?
We’ve tried:
-
/FU compiler option against the appropriate versions
-
#using against the appropriate versions
-
Specific Version reference in the .NET reference dialog using the strongly-named components.
None of these have been effective in getting the V2 assembly to be referenced.
Update: Here’s a bit more detail about the system, it is sensitive so I’ll stick with the A/B language above.
CommonAssembly.dll v1 and v2 (C#) strong-named
PluginA: C++/CLI compiled with /clr, CommonAssembly v1 referenced with /FU compiler option
PluginB: C++/CLI compiled with /clr, CommonAssembly v2 referenced with /FU compiler option
Main Application: Unmanaged — loads PluginA and PluginB at runtime with no direct references.
The unmanaged application loads PluginA, which loads CommonAssembly v1. The application then tries to load PluginB which requires CommonAssembly v2. The CLR tries to use the v1 instead and there is a TypeLoadException.
The mixed-mode assembly includes a native portion, and you can’t load more than one copy of this native portion into a single process.
Mixed-mode assemblies also don’t play well with AppDomains, because the native portion is process-wide.
You may have some luck with renaming one of the versions, since that’s how Windows tracks native DLLs.