如何解决在新的appdomain中加载程序集
我正在开发一个需要不同程序集的服务,但是在编译时我们不知道哪个程序集。因此,我想动态加载卸载不同的程序集。 我正在使用此代码进行加载,
static private void ExecuteAssemblyMethod(string taskName,string className,string method)
{
//load assembly in parent application domain,the assembly can not be unloaded.
var task = Assembly.LoadFrom($"tasks\\{taskName}.exe");
var myType = task.GetType($"{taskName}.{className}");
MethodInfo myMethod = myType.GetMethod(method);
object obj = Activator.CreateInstance(myType);
myMethod.Invoke(obj,null);
}
但是我发现只能通过卸载appdomain来卸载程序集。因此,它需要在可以卸载的其他appdomain中运行。但是我没有这个工作。我尝试了下面的代码,但由于CreateInstanceFrom返回类型为objecthandle而不是我期望的对象,因此无法正常工作。
static private void ExecuteAssemblyMethodInAppDomain(string taskName,string method)
{
//create child domain and load assembly within it. the appdomain can than be unloaded.
var dom = AppDomain.CreateDomain("taskDomain");
var task = dom.CreateInstanceFrom($"tasks\\{taskName}.exe",$"{ taskName}.{ className}");
Type myType = task.GetType();
MethodInfo myMethod = myType.GetMethod(method);
myMethod.Invoke(task,null);
AppDomain.Unload(dom);
}
解决方法
将评论后的答案更新为初始答案。
-
使用Unwrap来访问实例的直接方法不起作用,因为反射方法返回有关代理对象的信息,而不是返回目标类型的基础实例。
-
要解决此限制,需要将一个“已知”类型的对象注入到应用程序域中,以便反射代码在应用程序域中起作用。
代码:
HelperAssembly-包含一个简单的帮助程序类Helper.cs
namespace HelperAssembly
{
public class Helper : MarshalByRefObject
{
public void CreateAndRunPlugin(string assemblyName,string typeName,string methodName)
{
var task = AppDomain.CurrentDomain.CreateInstanceFromAndUnwrap(assemblyName,typeName);
Type myType = task.GetType();
MethodInfo myMethod = myType.GetMethod(methodName);
myMethod.Invoke(task,null);
}
}
}
启动任务的例程:
private static void TestAppDomain(string taskName,string className,string methodName)
{
//create child domain and load assembly within it. the appdomain can than be unloaded.
var dom = AppDomain.CreateDomain("taskDomain");
try
{
var whelper = dom.CreateInstanceFrom("path\\to\\HelperAssembly.dll","HelperAssembly.Helper");
var helper = (Helper)whelper.Unwrap();
helper.CreateAndRunPlugin($"path\\to\\{taskname}.exe",$"{taskName}.{className}",methodName);
return;
}
finally
{
AppDomain.Unload(dom);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。