从我的主要C#应用程序中,我通过反射实例化另一个应用程序。
assembly.CreateInstance( ... )
然而,这个其他程序集依赖于DLL,它们位于执行程序集之外的另一个目录中。如何将此目录添加到查找路径?
答案 0 :(得分:1)
以下是我们如何在NDepend.PowerTools中实现此需求。这些是基于NDepend.API的一组工具。 DLL NDepend.API.dll 位于.\Lib
目录中,而 NDepend.PowerTools.exe 程序集位于目录.\
中。
NDepend.PowerTools.exe Main()方法如下所示:
[STAThread]
static void Main() {
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolverHelper.AssemblyResolveHandler;
MainSub();
}
// MainSub() is here to avoids that the Main() method uses something
// from NDepend.API without having registered AssemblyResolveHandler
[MethodImpl(MethodImplOptions.NoInlining)]
static void MainSub() {
...
AssemblyResolverHelper
类是:
using System;
using System.Diagnostics;
using System.Reflection;
namespace NDepend.PowerTools {
internal static class AssemblyResolverHelper {
internal static Assembly AssemblyResolveHandler(object sender, ResolveEventArgs args) {
var assemblyName = new AssemblyName(args.Name);
Debug.Assert(assemblyName != null);
var assemblyNameString = assemblyName.Name;
Debug.Assert(assemblyNameString != null);
// Special treatment for NDepend.API and NDepend.Core because they are defined in $NDependInstallDir$\Lib
if (assemblyNameString != "NDepend.API" &&
assemblyNameString != "NDepend.Core") {
return null;
}
string binPath =
System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) +
System.IO.Path.DirectorySeparatorChar +
"Lib" +
System.IO.Path.DirectorySeparatorChar;
const string extension = ".dll";
var assembly = Assembly.LoadFrom(binPath + assemblyNameString + extension);
return assembly;
}
}
}
这适用于单个AppDomain。如果不需要,我不会在这里使用额外的AppDomain。 AppDomain是一个非常昂贵的工具(在性能方面)+跳转AppDomains边界的线程,必须序列化/反序列化输入/输出数据以提供汇编代码,这可能是一个令人头疼的问题。
AppDomain的唯一优势是它可以卸载已加载的程序集。因此,如果您希望在主AppDomain的生命周期内定期加载/卸载程序集,那么可以使用一些额外的临时AppDomain。