在appdomain中加载静态类

Wen*_*You 4 c# appdomain static-class

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

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

  1. 当我尝试加载它们时

    Assembly.LoadFrom("XXXXX") // (XXXXX is the full path of dll)
    
    Run Code Online (Sandbox Code Playgroud)

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

  2. 当我尝试在AppDomain中加载它们时

    adapterDomain = AppDomain.CreateDomain("AdapterDomain");
    (a)adapterDomain.CreateInstanceFrom(this.AdapterFilePath, this.AdapterFullName);
    (b)adapterAssembly=adapterDomain.Load(AssemblyName.GetAssemblyName(this.AdapterFilePath));
    
    Run Code Online (Sandbox Code Playgroud)

    如果我使用方法(a),因为目标类是静态类,它不起作用.

    如果我使用方法(b),因为目标.dll与我的项目不是同一个目录,我将得到一个例外.

如何加载.dll和静态类,然后在使用后卸载.dll?

Pan*_*nis 5

方法(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);
        }            
    }
}
Run Code Online (Sandbox Code Playgroud)

要完成这项工作,您需要更换:

  • PATH_TO_ASSEMBLY与包含静态方法的程序集的路径包括扩展名.
  • CLASS_CONTAINING_STATIC_METHOD with the name of the class containing the static method including the namespace of the class.
  • STATIC_METHOD with the name of the static method.

Note that the BindingFlags are set for public static methods.