在appdomain中加载静态类

我在C#AppDomain遇到了一个大问题。

我需要在.dll文件中加载一个静态类并执行它的方法:

  1. 当我尝试加载它们时

    Assembly.LoadFrom("XXXXX") // (XXXXX is the full path of dll) 

    .dll不会自动或以编程方式卸载。

  2. 当我尝试在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)失败,因为AppDomain.Load无法解析不在基本应用程序目录,探测专用路径或GAC中的程序集。

另请注意, AppDomain.Load 在特定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是为公共静态方法设置的。