I'm implementing application that supports plugins. Currently the problem arises when I try to load common assembly that is used both by host application and plugin: host application should use one version of that assembly, while plugin uses another version. This is dictated by application upgrade process - plugin can be updated separately from host application.
Every assembly is signed, so I use strong names for loading assemblies.
I created a test application which demonstrates the problem. Plugin assemblies are located in subfolder 'Plugin' of host application. Plugin folder contains the plugin implementation DLL, plugin declaration interface DLL and CommonLib DLL. Host application also use plugin declaration DLL and CommonLib DLL (located 1 level up in folder tree).
Here is source code of plugin loading:
static void Main(string[] args)
{
Console.WriteLine("Host says: {0}", GreetingManager.SayHello("Sasha"));
Console.WriteLine("Host says: {0}", GreetingManager.SayGoodBye("Sasha"));
var pluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugin");
var pluginFile = Directory.GetFiles(pluginDir).First(f => f.EndsWith("Plugin.dll"));
Assembly asmr = Assembly.ReflectionOnlyLoadFrom(pluginFile);
AppDomain pluginDomain = AppDomain.CreateDomain("Plugin", null, pluginDir, "", false);
pluginDomain.Load(asmr.FullName);
Assembly asm = pluginDomain.GetAssemblies().First(a => a.GetName().Name == "Plugin");
Type p = asm.GetTypes().First(t => t.GetInterfaces().Contains(typeof(IPlugin)));
var pluginInstance = (IPlugin)pluginDomain.CreateInstanceAndUnwrap(asm.FullName, p.FullName);
Console.WriteLine("Plugin says: {0}", pluginInstance.TransformString("Sasha"));
}
It throws exception:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'CommonLib, Version=1.0.9.0, Culture=neutral, PublicKeyToken=73c7c163a33b622c' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
at Plugin.MyPlugin.TransformString(String str)
at PluginBackwardCompatibilityTest.Program.Main(String[] args) in D:ProjectsTestPluginBackwardCompatibilityTestPluginBackwardCompatibilityTestProgram.cs:line 37
As I udnerstand, plugin still tries to find CommonLib assembly in the host application folder (ignoring the appBasePath parameter I provided when creating AppDomain), but finds older version 1.0.8 there and generates this error. How can I force plugin to load referenced assemblies from Plugin folder - there is no way to specify full assembly path to load when using strong name.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…