如何动态引用查找另一个程序集的程序集?

时间:2013-09-22 10:29:39

标签: c# powershell reflection assembly-resolution

为狡猾的问题道歉 - 如果有人有更好的建议,我很乐意改写。

我正在尝试通过动态调用属于另一个应用程序的程序集来创建一个对象。

以下PowerShell代码对我很有用:

[Reflection.Assembly]::LoadFrom("C:\Program Files\Vendor\Product\ProductAPI.dll")
$bobject = new-object ProductAPI.BasicObject    
$bobject.AddName("Some Name") 

我在C#中努力做同样的事情。基于StackOverflow上的其他帖子,我目前有这个:

System.Reflection.Assembly myDllAssembly =
System.Reflection.Assembly.LoadFile("C:\\Program Files\\Vendor\\Product\\ProductAPI.dll");

System.Type BasicObjectType = myDllAssembly.GetType("ProductAPI.BasicObject");

var basicObjectInstance = Activator.CreateInstance(BasicObjectType);

最后一行导致TargetInvocationException。

  

{“无法加载文件或程序集'AnotherObject,Version = 1.2.345.0,Culture = neutral,PublicKeyToken = null'或其依赖项之一。系统找不到指定的文件。”

看起来BasicObject构造函数试图调用AnotherObject(来自同一文件夹中的AnotherObject.dll)但找不到它。

有关如何解决此问题的任何提示?

1 个答案:

答案 0 :(得分:7)

如果在the usual places中找不到依赖程序集,则需要手动指定查找方法。

我知道这两个最简单的方法:

  1. 事先手动加载从属程序集 Assembly.Load

  2. 处理正在加载的域的AssemblyResolve事件 具有其他程序集依赖性的程序集。

  3. 这两者基本上都要求你知道你试图提前加载的程序集的依赖关系,但我认为这不是一个很大的问题。

    如果您选择第一个选项,那么查看完整加载和reflection-only Load之间的差异也是值得的。

    如果您更愿意使用2(我推荐),您可以尝试使用嵌套依赖链(例如MyLib.dll引用LocalStorage.dll引用Raven)的额外好处。 .Client.dll引用NewtonSoft.Json.dll)并将另外提供有关它无法找到的依赖项的信息:​​

    AppDomain.CurrentDomain.AssemblyResolve += (sender,args) => {
    
        // Change this to wherever the additional dependencies are located    
        var dllPath = @"C:\Program Files\Vendor\Product\lib";
    
        var assemblyPath = Path.Combine(dllPath,args.Name.Split(',').First() + ".dll");
    
        if(!File.Exists(assemblyPath))
           throw new ReflectionTypeLoadException(new[] {args.GetType()},
               new[] {new FileNotFoundException(assemblyPath) });
    
        return Assembly.LoadFrom(assemblyPath);
    };