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

gf1*_*072 6 c# reflection powershell assembly-resolution

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

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

以下PowerShell代码对我很有用:

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

我在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);
Run Code Online (Sandbox Code Playgroud)

最后一行导致TargetInvocationException.

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

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

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

nat*_*ere 7

如果在常用位置找不到依赖程序集,需要手动指定如何查找它们.

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

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

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

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

如果您选择第一个选项,那么查看完整加载和仅反射加载之间的差异也是值得的.

如果您更愿意使用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);
};
Run Code Online (Sandbox Code Playgroud)