【问题标题】:How to load assemblies to the current app domain to the c# project dynamically?如何将当前应用程序域的程序集动态加载到c#项目中?
【发布时间】:2015-06-12 05:16:33
【问题描述】:

我正在尝试将第三方assemblies 动态 加载到项目中,并使用reflection 创建其类型的实例。

我用过:

Assembly.LoadFrom("Assembly1.dll")
Assembly.LoadFrom("Assembly2.dll")
Assembly.LoadFrom("Assembly3.dll") 

也试过了:

AppDomain.CurrentDomain.Load("Assembly1.dll")
AppDomain.CurrentDomain.Load("Assembly2.dll")
AppDomain.CurrentDomain.Load("Assembly3.dll") 

但是,当我尝试创建以下类型之一的实例时,我不断收到The method is not implemented 异常:

Assembly.LoadFrom("Assembly1.dll")
Assembly.LoadFrom("Assembly2.dll")
Assembly assembly=  Assembly.LoadFrom("Assembly3.dll")
Type type=assembly.GetType("Assembly3.Class1")
object instance=Activator.CreateInstance(type); //throws exception at this point

但是,如果我在项目中直接add referenceAssembly1、Assembly2 和Assembly3 并这样做:

Assembly3.Class1 testClass=new Assembly3.Class1();

我也不例外

我只是想知道我做错了什么?如何动态地将程序集加载到项目中。我猜,因为Class1 实例的创建依赖于另一个程序集Assembly1Assembly2,所以它失败了。那么,如何将所有依赖程序集动态加载到appdomain/loadcontext

非常感谢您的回答。

【问题讨论】:

  • 在另一个帖子中回复:stackoverflow.com/a/18362459/4997569
  • 不是真的!即仅加载 一个程序集 并将其实例化为 type。我已经试过了。但是没有用。我有 多个程序集 加载到“当前上下文”并创建一个实例

标签: c# .net .net-assembly


【解决方案1】:

要解决依赖关系,您需要处理 AppDomain.AssemblyResolve Event

using System;
using System.Reflection;

class ExampleClass
{
    static void Main()
    {
        AppDomain ad = AppDomain.CurrentDomain;

        ad.AssemblyResolve += MyAssemblyResolveHandler;

        Assembly assembly = ad.Load("Assembly3.dll");

        Type type = assembly.GetType("Assembly3.Class1");

        try
        {
            object instance = Activator.CreateInstance(type);
        } 
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    static Assembly MyAssemblyResolveHandler(object source, ResolveEventArgs e) 
    {
        // Assembly.LoadFrom("Assembly1.dll")
        // Assembly.LoadFrom("Assembly2.dll")

        return Assembly.Load(e.Name);
    }
}

MyAssemblyResolveHandler 为每个未加载的程序集触发,包括依赖项。

【讨论】:

  • 这会导致无限循环调用 Assembly.Load(e.name) 调用 CurrentDomain 的 ResolveHandler
【解决方案2】:

当使用“ad.AssemblyResolve += MyAssemblyResolveHandler”时,我得到了“cdie”描述的无限循环。

所以我尝试了几件事。以下是通过 MSDN LoadFrom link

public object InitClassFromExternalAssembly(string dllPath, string className)
{
    try
    {
        Assembly assembly = Assembly.LoadFrom(dllPath);
        Type type = assembly.GetType(className);
        var instance = Activator.CreateInstance(type);
        return instance;
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

显然,Assembly.LoadFrom 方法需要 DLL 的完整路径。

请注意链接中通过 LoadFrom 加载程序集时可能出现的问题。

另外,上面'ArcangelZith' 包含的link 也有一些有趣的想法。

【讨论】:

    【解决方案3】:

    如果引用了程序集,您可以这样做以按名称加载它

    AppDomain.CurrentDomain.Load(new AssemblyName("Assembly1.Core"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 2013-11-30
      相关资源
      最近更新 更多