在appdomain中加载静态类 [英] Load static class in appdomain

查看:125
本文介绍了在appdomain中加载静态类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

  1. 当我尝试加载它们时

  1. When I try to load them by

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

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

the .dll will not be unload automatically or programmatically.

当我尝试将它们加载到AppDomain中时

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));

如果我使用方法(a),则由于目标类是静态类,所以它不起作用.

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

如果我使用方法(b),则由于目标.dll与项目所在的目录不同,因此会出现异常.

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

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

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

推荐答案

方法(b)失败,因为 AppDomain.Load 无法解析不在基本应用程序目录,探测专用路径或GAC中的程序集.

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

还请注意,AppDomain.Load不会加载特定AppDomain上的程序集(例如示例代码中的adapterDomain.Load).而是将其加载到当前的AppDomain上(这是对AppDomain.Load的调用.在

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.

下面是一个有关如何在子AppDomain中调用静态方法的示例:

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,其程序集的路径包含包含扩展名的静态方法.
  • CLASS_CONTAINING_STATIC_METHOD,其类名称包含包含类名称空间的静态方法.
  • STATIC_METHOD,带有静态方法的名称.

请注意,BindingFlags是为公共静态方法设置的.

Note that the BindingFlags are set for public static methods.

这篇关于在appdomain中加载静态类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆