从内存而不是磁盘加载.NET程序集

时间:2013-11-19 19:01:55

标签: c# .net .net-assembly assembly-resolution

我在尝试从内存而不是从磁盘加载.NET程序集时遇到了一个令人困惑的问题。如果我编译程序集然后从磁盘加载它(使用LoadFile或LoadFrom),那么应用程序工作正常。

但是,如果我将已编译的程序集DLL文件作为嵌入资源包含在项目中,然后使用Assembly.Load从资源流加载字节,那么随着应用程序继续运行,我会收到一系列随机错误。

这只是应用程序中八个程序集之一的问题 - 所有其他程序都可以从磁盘或内存中正常工作。

感谢您的帮助!

1 个答案:

答案 0 :(得分:13)

你还没有提供足够的细节来猜测你的问题是什么。但是,我可以呈现我使用的模式。

我处理嵌入依赖程序集的方法是使用AssemblyResolve事件。您将事件连接一次然后如果CLR在磁盘上找不到程序集,它将引发此事件。引发事件时,从资源清单中提取汇编位并调用Assembly.Load

以下是代码的外观。

internal class AssemblyResolver
{
  public static void Register()
  {
    AppDomain.CurrentDomain.AssemblyResolve +=
      (sender, args) =>
      {
        var an = new AssemblyName(args.Name);
        if (an.Name == "YourAssembly")
        {
          string resourcepath = "YourNamespace.YourAssembly.dll";
          Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcepath);
          if (stream != null)
          {
            using (stream)
            {
              byte[] data = new byte[stream.Length];
              stream.Read(data, 0, data.Length);
              return Assembly.Load(data);
            }
          }
        }
        return null;
      }
  }
}

然后就可以这样使用。

public static void Main()
{
  // Do not use any types from the dependent assembly yet.

  AssemblyResolver.Register();

  // Now you can use types from the dependent assembly!
}

我已成功使用此模式多年。有一些警告,但在大多数情况下它运作良好。它肯定比使用ILMerge工具好很多。