AppDomain appDomain = AppDomain.CreateDomain("MyDomain");
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "DLLs (*.dll)|*.dll";
if (dialog.ShowDialog().Value)
{
string newLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + dialog.SafeFileName;
File.Copy(dialog.FileName, newLocation, true);
Assembly assembly = appDomain.Load(AssemblyName.GetAssemblyName(newLocation));
UserControl userControl = (UserControl) assembly.CreateInstance("WpfControlLibrary1.UserControl1");
}
我现在使用以下代码将UserControl添加到Grid中:
grid.Children.Add(userControl);
工作正常。现在我尝试使用以下方式卸载DLL:
AppDomain.Unload(appDomain);
grid.Children.Clear();
如果我现在尝试使用上述代码再次加载DLL(因为它在此期间已更改),我会收到一个错误,告诉我文件正在使用中(File.Copy)。
我读了很多东西,我的猜测是我不能像之前那样使用UserControl(因为它加载到主AppDomain中)。我该如何更改代码才能使其正常工作?
我也读了很多关于使用MarshalByRefObject的东西,但不幸的是我无法在这个项目中实现它。希望能提供一个示例或修改上面的代码。
编辑:
从我迄今为止阅读的评论中(特别是来自svick的评论),看起来我必须使用“AppDomain.CreateInstanceAndUnwrap”而不是“AppDomain.Load”。我在搜索解决方案时已经看到过这种方法,但正如svick所提到的,这行不通,因为UserControl无法继承自MarshalByRefObject。
有人知道其他方法吗?
MarhshalByRefObject
建议以及远程对象的常见接口。这很难,但一旦你理解了,你就会明白 :) 顺便说一句,这是学习远程调用的好练习。 - leppie