我正在开发一个服务在后台连续运行的解决方案,并且可以在运行时添加/删除插件 DLL。该服务将在需要时加载必要的插件,运行它们并卸载它们。这是当前给我带来麻烦的卸载部分:一旦某个类第一次成功加载(变量 tc),即使更新了 DLL 文件,它也永远不会重新加载。我想我没有正确卸载类/程序集/应用程序域,所以我很感激一些关于走最后一英里的建议。
编辑:我更新了帖子以反映最近的代码更改,并解释了卸载何时没有效果:问题没有出现在 Linux Ubuntu(通过 Mono)上,但它出现在 Windows 2008 Server 上,当我试图用较新的文件版本替换某个插件 DLL。似乎 .NET 框架已将程序集缓存在某处,并且无需重新加载它就很高兴。DLL 文件名没有改变,但 File Version 属性不同,所以我希望运行时将先前加载的 DLL 版本与正在加载的版本进行比较,如果版本号不同,则使用较新的版本。如果我稍微更改代码以从具有不同名称的 DLL 文件加载程序集,则重新加载会按预期进行。
using System;
using System.Reflection;
namespace TestMonoConsole
{
public interface ITestClass
{
void Talk();
}
class MainClass
{
public static void Main (string[] args)
{
string pluginPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string classAssembly = "TestClass";
string className = "TestMonoConsole.TestClass";
string command = "";
do
{
try
{
System.AppDomain domain = System.AppDomain.CreateDomain(classAssembly);
string pluginAssemblyFile = pluginPath + "/" + classAssembly + ".dll";
System.IO.StreamReader reader = new System.IO.StreamReader(pluginAssemblyFile, System.Text.Encoding.GetEncoding(1252), false);
byte[] b = new byte[reader.BaseStream.Length];
reader.BaseStream.Read(b, 0, System.Convert.ToInt32(reader.BaseStream.Length));
domain.Load(b);
reader.Close();
ITestClass tc = (ITestClass) Activator.CreateInstance(domain, classAssembly, className).Unwrap();
tc.Talk();
System.AppDomain.Unload(domain);
}
catch (System.IO.FileNotFoundException e)
{
Console.WriteLine (String.Format("Error loading plugin: assembly {0} not found", classAssembly));
}
command = Console.ReadLine();
} while (command == "");
}
}
}