【问题标题】:Load static class in appdomain在 appdomain 中加载静态类
【发布时间】:2013-09-16 05:36:22
【问题描述】:

我在 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?

【问题讨论】:

  • 您无法卸载 DLL。您可以卸载 AppDomain
  • 但是我无法将DLL中的静态类添加到AppDomain..
  • 看了 Josh 的链接后,我没有找到解决问题的方法,本文介绍的方法都是关于普通类的,但我想加载一个静态类到 AppDomain

标签: c# appdomain static-class


【解决方案1】:

方法 (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);
        }            
    }
}

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

  • PATH_TO_ASSEMBLY 包含包含扩展的静态方法的程序集路径。
  • CLASS_CONTAINING_STATIC_METHOD 与包含静态方法的类的名称,包括类的命名空间。
  • STATIC_METHOD 带有静态方法的名称。

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

【讨论】:

  • 是的,它适用于你的方法,但还有一点需要注意:定义 AppDomain 的方法必须是静态方法。
  • @WenchaoYou 不一定是静态方法。您可以在子 AppDomain 中创建一个中间对象来执行加载。 stackoverflow.com/a/17324102/850119
  • 是的!我已经按照你的指导和MSDN页面【link】第三个案例,非常感谢你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多