Monday, December 22, 2014

Embedding DLL's

I've faced this problem before, and ended up with the same solution: I have to deploy a solution that is composed of more than one file, usually an exe and a set of DLL's.

But the deployment process expects only a single file. With Java, this is simple; Maven can pack every dependency together and a single jar file is generated for your application. But how we solve this with .NET and it's multiple DLL nature?

 MSFT Research created a tool for that, called ILMerge.

However, this tool has shortcomings, such as it's unability to work with WPF. Now, what I've done in the past (when I needed to include a native DLL to do some interop, actually) is much more like the solution presented here. In short, all you do is embed the DLL's as resources in your main assembly (be it a executable or library), and add an event handler to the AssemblyResolve property of the current appdomain

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {

   String resourceName = "AssemblyLoadingAndReflection." + new AssemblyName(args.Name).Name + ".dll";

   using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) 
   {
      Byte[] assemblyData = new Byte[stream.Length];
      stream.Read(assemblyData, 0, assemblyData.Length);
      return Assembly.Load(assemblyData);
   }
}

This will result in the appdomain loading the embedded DLL as resources. The code above can be adapted to even load executables if necessary.