.NET在运行时添加依赖项目录

时间:2014-03-24 09:21:54

标签: c# .net dll dependencies

从我的主要C#应用程序中,我通过反射实例化另一个应用程序。

assembly.CreateInstance( ... )

然而,这个其他程序集依赖于DLL,它们位于执行程序集之外的另一个目录中。如何将此目录添加到查找路径?

1 个答案:

答案 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。