我遇到了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?
答案 0 :(得分:5)
方法(b)失败,因为AppDomain.Load无法解析不在基本应用程序目录,探测私有路径或GAC中的程序集。
另请注意,AppDomain.Load
不在特定AppDomain上加载程序集(如示例代码中的adapterDomain.Load
)。相反,它将它加载到当前的AppDomain上(这是调用AppDomain.Load
的人。这个行为在MSDN documentation上被注明。)显然这不是你想要的。
以下是如何在子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);
}
}
}
要完成这项工作,您需要替换:
请注意,BindingFlags
是为公共静态方法设置的。