Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading .NET Assembly From Memory Instead of Disk [closed]

I am having a perplexing problem trying to load a .NET assembly from memory instead of from the disk. If I compile the assembly and then load it from disk (either using LoadFile or LoadFrom), then the application works just fine.

However, if I include the compiled assembly DLL file as an embedded resource in the project and then use Assembly.Load to load the bytes from the resource stream, then I get a series of random errors as the application continues to run.

This is only a problem on one of eight assemblies in the application - all of the others work fine from either the disk or memory.

Thanks for the help!

like image 331
user986713 Avatar asked Nov 19 '13 19:11

user986713


1 Answers

You have not provided enough detail for me to even guess at what your problem is. However, I can present the pattern I use.

The way I handle embedding dependent assemblies is to use the AssemblyResolve event. You wire up the event once and then if the CLR cannot find the assembly on disk it will raise this event. When the event is raised then you extract the assembly bits from the resource manifest and call Assembly.Load.

Here is what the code might look like.

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;
      }
  }
}

And then it can be used like this.

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!
}

I have used this pattern successfully for many years. There are a few caveats, but for the most part it works well. It is certainly a lot better than using the ILMerge tool.

like image 177
Brian Gideon Avatar answered Nov 02 '22 00:11

Brian Gideon