Monday, November 28, 2011

.NET assembly merging, three different approaches...

simonebu's space - Past, present and future of .NET assembly merging

Compiling code written for the .NET framework usually produces assemblies in the form of either standalone executables or libraries. These assemblies contain mainly Microsoft Intermediate Language (MSIL) code which is then jitted upon execution.

It's not uncommon for libraries which expose public APIs to rely internally on assemblies provided by third parties that should not end up in the final package. I'll take the mocking library NSubstitute as an example.

There are commonly a couple of reasons why they shouldn't. First, the client code does not need to reference them directly as they are only used internally. Back to the mocking framework example, it wouldn't make a lot of sense to build a dynamic proxy from scratch as there exist excellent implementations already, like Castle DynamicProxy, which NSubstitute uses.
The other reason is to avoid cluttering the release package of the library with dependencies that are of no interest to the end user, thus simplifying the distribution of the library which would then consist of a smaller number of files.

The aim is thus to embed somehow the dependent assemblies in a single assembly. There has been mainly a single approach to this so far, and it's called ILMerge.

ILMerge

Mike Barnett's ILMerge is a free tool which statically links several assemblies into a single output assembly. It runs as a console application and rewrites the IL of the main assembly by embedding the contents of the other assemblies into it. It takes care of a couple of additional things, like strong naming and target framework version, but accepts additional configuration options which allow further customization. One particularly useful is internalization of types, which allows to change the accessibility levels of the types contained in the dependent assemblies, thus effectively hiding them to everyone except the containing assembly.

...

Embedding assemblies as resources

Serializing other files into assemblies as resources has always been possible. Resources can then be deserialized at runtime and manipulated. They can be anything, although commonly used for storing media, icons and inanimate data in general. Nothing prevents you from storing assemblies in there, and load them at runtime...

...

Costura

Costura is a neat open source project developed by Simon Cropp which takes care of all the steps described above, and is thereby the suggested way to merge third party assemblies using the embedded resource approach. ..."

I've been following ILMerge for forever, and like the concept behind it (i.e. simplifying deployment). That said, this is the first  I've heard of Costura. Needless to say I'm watching it now... :)

1 comment:

TomPester said...

Costura works very well. I tried it for a winform and wpf application and it did work from the first time, went into production and haven't had issues with it other then the IoC container which had to be adjusted a bit.