Load static class in appdomain

微笑、不失礼 提交于 2019-12-30 07:04:41

问题


I'm met with a big problem in C# AppDomain.

I need to load a static class in a .dll file and execute its method:

  1. When I try to load them by

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

    the .dll will not be unload automatically or programmatically.

  2. When I try to load them in AppDomain like

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

    If I use method (a), because the target class is a static one, it doesn't work.

    If I use method (b), because the target .dll is not the same directory with my project, I will get an exception.

How can I load the .dll and the static class, and then unload the .dll after my usage?


回答1:


Method (b) fails because AppDomain.Load cannot resolve assemblies that are not in the base app dir, the probing private paths or the GAC.

Also note that the AppDomain.Load is not loading the assembly on the specific AppDomain (like adapterDomain.Load in your sample code). Instead it is loading it on the current AppDomain (this is the one making the call to AppDomain.Load. This behavior is remarked on the MSDN documentation.) Apparently this is not what you are looking for.

Here's an example on how to call a static method in the child 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);
        }            
    }
}

To make this work you will need to replace:

  • PATH_TO_ASSEMBLY with the path of the assembly containing the static method including the extension.
  • 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.



来源:https://stackoverflow.com/questions/18753995/load-static-class-in-appdomain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!