我在 C# AppDomain 中遇到了一个大问题。
我需要在 .dll 文件中加载静态类并执行其方法:
-
当我尝试通过以下方式加载它们时
Assembly.LoadFrom("XXXXX") // (XXXXX is the full path of dll)
.dll 不会自动或以编程方式卸载。
-
当我尝试将它们加载到 AppDomain 中时
adapterDomain = AppDomain.CreateDomain("AdapterDomain");
(a)adapterDomain.CreateInstanceFrom(this.AdapterFilePath, this.AdapterFullName);
(b)adapterAssembly=adapterDomain.Load(AssemblyName.GetAssemblyName(this.AdapterFilePath));
如果我使用方法(a),因为目标类是静态类,所以不起作用。
如果我使用方法(b),因为目标.dll与我的项目不在同一目录,我会得到一个异常。
如何加载 .dll 和静态类,然后在使用后卸载 .dll?
方法 (b) 失败是因为应用程序域.加载无法解析不在基本应用程序目录、探测专用路径或 GAC 中的程序集。
另请注意,AppDomain.Load
is not在特定的 AppDomain 上加载程序集(例如adapterDomain.Load
在您的示例代码中)。相反,它会将其加载到当前的 AppDomain 上(这是调用AppDomain.Load
。此行为已在MSDN 文档.)显然这不是您正在寻找的。
以下是如何在子 AppDomain 中调用静态方法的示例:
class Program
{
static void Main(string[] args)
{
// This is for testing purposes!
var loadedAssembliesBefore = AppDomain.CurrentDomain.GetAssemblies();
var domain = AppDomain.CreateDomain("ChildDomain");
// This will make the call to the static method in the dhild AppDomain.
domain.DoCallBack(LoadAssemblyAndCallStaticMethod);
// Print the loaded assemblies on the child AppDomain. This is for testing purposes!
domain.DoCallBack(PrintLoadedAssemblies);
AppDomain.Unload(domain);
// This is for testing purposes!
var loadedAssembliesAfter = AppDomain.CurrentDomain.GetAssemblies();
// Assert that no assembly was leaked to the main AppDomain.
Debug.Assert(!loadedAssembliesBefore.Except(loadedAssembliesAfter).Any());
Console.ReadKey();
}
// Loads StaticMethodInHere.dll to the current AppDomain and calls static method
// StaticClass.DoSomething.
static void LoadAssemblyAndCallStaticMethod()
{
var assembly = Assembly.LoadFrom(@"PATH_TO_ASSEMBLY");
assembly.GetType("CLASS_CONTAINING_STATIC_METHOD")
.InvokeMember("STATIC_METHOD",
BindingFlags.Public |
BindingFlags.Static |
BindingFlags.InvokeMethod,
null,
null,
null);
}
// Prints the loaded assebmlies in the current AppDomain. For testing purposes.
static void PrintLoadedAssemblies()
{
Console.WriteLine("/ Assemblies in {0} -------------------------------",
AppDomain.CurrentDomain.FriendlyName);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
Console.WriteLine(assembly.FullName);
}
}
}
为了使这项工作有效,您需要替换:
- PATH_TO_ASSEMBLY 为包含静态方法(包括扩展)的程序集的路径。
- CLASS_CONTAINING_STATIC_METHOD 是包含静态方法的类的名称,包括该类的命名空间。
- STATIC_METHOD 带有静态方法的名称。
请注意,BindingFlags
为公共静态方法设置。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)