Alain
Alain

Reputation: 27220

How to pack referenced libraries into a new libarary

When creating a new library MyAPI.dll, I am referencing many other (non-standard) libraries such as RestSharp.dll, Newtonsoft.dll,MyUtilities.dll, etc. My library works fine in my development environment because I've downloaded all of those other libraries and they're sitting in my project's bin folder, but as soon as I try to publish that library and use it in a new location, it fails because the referenced libraries cannot be found.

How to I set up my MyAPI.csproj project so that these dlls/libraries get packaged into my published .dll file, and future users of MyAPI.dll don't have to worry about downloading and referencing those dependencies?

Thought this would be simple, but my google-fu is weak today. Setting those external references to CopyLocal = False removes them from the /bin/ directory, giving the illusion that they are getting packaged into MyAPU.dll, but really Visual Studio is just adding them to my Global Assembly Cache (GAC), which doesn't help future users of the API.

Upvotes: 1

Views: 3042

Answers (3)

Laika42
Laika42

Reputation: 91

There is a free nuget package "Costura.Fody" it packs dependency assemblies as resources into your assembly. The solution works with WPF and other managed assemblies.

If the dependency assemblies are not in the executing folder, the packed assemblies are taken automaitcally. It also configures your msbuild targets automatically for packing the dependencies during build. You do not have to add code in your assemblies. It also lets you configure, which assemblies to pack or not in a xml file.

It uses a combination of two methos:

  • Jeffrey Richter's suggestion of using embedded resources as a method of merging assemblies.
  • Einar Egilsson's suggestion using cecil to create module initializers.

You can find documentation here: https://github.com/Fody/Costura/blob/master/README.md

Upvotes: 3

Krtek
Krtek

Reputation: 66

There are two options (as far as i know):

  1. ILMerge
  2. Embeded Resource and Assembly.Resolve (see Jeffrey Richter)

First you can use ILMerge, which is comamndline program that can merge multiple .NET assemblies together, creating one output file. It cant merge WPF projects. Can be added to postbuild events to make the merge automatic.

Second is adding library as embeded resource to your project, and then registering to Assembly.Resolve event and loading assembly when its needed from resources. Article from Jeffrey Richter about this method: Jeffrey Richter.

The second method has major drawback, it doesnt work with merging multiple libraries into one (it can only be used for adding libraries to executable), at least in c# without another tool. To add library to library you have to use another tool, which is mentioned in Jeffrey's article comments at second page: (Module initializer injection).The problem with embeding library into other library is that you cant (at least in c#) register to Assembly.Resolve event before the embeded library is needed, so you need to inject the registering to module initializer using the Module initializer injection. It can also be set as build event, which is written on the apge with the tool. It may sounds complicated, but once you set it up its easy.

Upvotes: 4

JMK
JMK

Reputation: 28059

It's not free (well there's a trial) but a friend of mine told me about a program called .NET Reactor, which has the ability to package an exe with dependent DLL's into a single executable, well worth a look.

I would say the next most straight-forward alternative would be ClickOnce, a good tutorial is here.

Upvotes: 0

Related Questions