Sas*_*sha 3 .net c# clr appdomain
我正在实现支持插件的应用程序。当前,当我尝试加载由主机应用程序和插件使用的通用程序集时,会出现问题 :主机应用程序应使用该程序集的一个版本,而插件使用另一版本。这由应用程序升级过程决定-插件可以与主机应用程序分开进行更新。
每个程序集都经过签名,因此我使用强名称来加载程序集。
我创建了一个演示该问题的测试应用程序。插件程序集位于主机应用程序的子文件夹“ Plugin”中。Plugin文件夹包含插件实现DLL,插件声明接口DLL和CommonLib DLL。主机应用程序还使用插件声明DLL和CommonLib DLL(位于文件夹树中的上一级)。
这是插件加载的源代码:
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"));
}
Run Code Online (Sandbox Code Playgroud)
它引发异常:
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:\Projects\Test\PluginBackwardCompatibilityTest\PluginBackwardCompatibilityTest\Program.cs:line 37
Run Code Online (Sandbox Code Playgroud)
如我所知,插件仍然尝试在主机应用程序文件夹中查找CommonLib程序集(忽略我在创建AppDomain时提供的appBasePath参数),但是在那里找到了较旧的版本1.0.8并生成此错误。如何强制插件从“插件”文件夹加载引用的程序集 -使用强名称时,无法指定要加载的完整程序集路径。
我认为您的问题如下:
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);
Run Code Online (Sandbox Code Playgroud)
这样,您就可以将更新/过时的类型引用加载到主AppDomain中(该程序集已经以其他版本加载了该程序集)。
我建议您使用以下方法:
我不能说这是否是最好的版本,但是在每个插件都可以加载任何程序集的任何版本的环境中,这个版本对我来说效果很好。使用此设置,您几乎可以拒绝更改版本或更新,并且每个插件都可以使用所需的版本。
请让我知道这对你有没有用。
| 归档时间: |
|
| 查看次数: |
1678 次 |
| 最近记录: |