6

为这个狡猾的问题道歉 - 如果有人有更好的建议,很高兴重新措辞。

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

以下 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)但找不到它。

关于如何解决这个问题的任何提示?

4

1 回答 1

8

如果在通常的地方找不到依赖程序集,则需要手动指定如何找到它们。

我知道这样做的两种最简单的方法:

  1. 使用Assembly.Load提前手动加载依赖程序集 。

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

两者本质上都要求您提前了解您尝试加载的程序集的依赖关系,但我认为这不是一个大问题。

如果您使用第一个选项,那么研究完整 Load 和仅反射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);
};
于 2013-09-22T11:06:57.153 回答