• Stars
    star
    220
  • Rank 180,422 (Top 4 %)
  • Language
    C#
  • License
    Other
  • Created about 9 years ago
  • Updated about 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

LibZ, the alternative to ILMerge

LibZ, the alternative to ILMerge

LibZ is an alternative to ILMerge. It allows you to distribute your applications or libraries as a single file with assemblies embedded into it or combined together into a container file.

Migration from codeplex

I believe sources and documentation have been fully migrated but you can still access old website here

License

Lib is licensed under Ms-PL. Long story short - you can use it, you can modify it as long as you don't claim you wrote it.

Change log

Changes can found here

Why not ILMerge?

ILMerge in many cases is the first thing you tried and it does what it does just fine, sometimes you just don't want it to do what it does, you just don't know that yet. Problems start to appear when your application uses reflection, or even worse, when 3rd part libraries use reflection. The alternative is "embedding" instead of "merging". Jeffrey Richter described this technique on his blog (and in his book) a few years ago. I think the best recommendation is the comment from Mike Barnett, author of ILMerge: "As the author of ILMerge, I think this is fantastic! If I had known about this, I never would have written ILMerge. Many people have run into problems using ILMerge for WPF applications because WPF encodes assembly identities in binary resources that ILMerge is unable to modify. But this should work great for them."

Download

Probably the best way to download it is to use the NuGet package LibZ.Tool. For advanced use (see: Scenarios) you may consider using other packages (LibZ.Library or LibZ.Sources) but only if you really know why (therefore, I'm not even linking to them from here).

Before you start

LibZ Container is not better than ILMerge, IL-Repack, Costura.Fody, etc. They do what they do well, they just lacked some features I needed (so I implemented them in LibZ). They also had some features which I didn't need (so I didn't implement them in LibZ). Carefully read what LibZ does and doesn't do before making a call. Some things I didn't like are just bugs (so they can be fixed sooner of later) some of them are just by design (and let me repeat, not bad design, just design for different purpose).

Motivation

There are multiple things which motivated me to write this library / tool.

  • First of all I do like small single-purpose assemblies, so they can be composed in many different ways and not introduce too much unused code. Frequently, when looking for some libraries (github, codeplex) I find them interesting, I'm just put off by the fact that 90% of that library is something I've already written for myself (and I prefer mine). I just won't use a library saying "many utilities doing many things". Sorry. Be specific. Do one thing. Do it well. With all the respect for the author of Json.NET I just don't think his Utilities.NET should be distributed as one assembly. I've implemented 90% of it myself already, why can't I just pick parts which I need.
  • So I do use small assemblies. I don't like a lot of assemblies in distributables, though. They (distributables) should be sleek. One file preferably.
  • I was using ILMerge for quite some time, but ILMerge has a lot of disadvantages. First of all it does not work (by definition) if assemblies / classes are referenced from code using their strong name. During merge assemblies lose their identity and they all get injected into one big bag of code. WPF? NHibernate (XML driven)? Nope. It won't work.
  • Obfuscators can merge assemblies but they do have same problem as ILMerge - assemblies lose identity. Even worse - classes lose their names (that's, of course, what you want when using obfuscation), so you should be very careful with it and the only proof that it really works is full system test including UI. Using a framework which uses reflection? Say goodbye to it. See: NHibrnate, Caliburn.Micro, Dapper. It can be done, of course with configuration files/attributes saying "do no obfuscate this, do not obfuscate that". It's just a lot of work. And you constantly ask yourself: "did I miss something?". Some obfuscators (I have one particular in mind, but I won't name it) allow you to embed assemblies without merging them, but in such case it becomes a quite overpriced toy.
  • So, LibZ allows you to embed required assemblies as resources and automatically instrument your main assembly (executable) with a resolver. No code needed. You write absolutely nothing.
  • I had one project though, where there was multiple entry points. 5 console applications, and 2 GUIs - all in one folder. They all shared a lot of code-base (2 MB for console applications and 15MB for GUIs). It was something like 50 assemblies. NHibernate, DevExpress, NLog - you name it. The choice was to not embed assemblies (and have 50 assemblies in one folder) or embed them and have 7 enormous executables with lot of assemblies duplicated inside them). So I came with an idea of a 'container file' (something like .jar in Java or .xap in Silverlight) which can be shared by all of them. I ended up with 7 small executables (30KB each) and some containers (for example: NHibernate.libz, DevExpress.libz, MyCompany.Core.libz and Utilities.libz).
  • I didn't want to use Zip for the container, because it would introduce the dependency on some Zip library (probably DotNetZip. So I came up with much simpler container using built-in deflate, but extensible with additional compression algorithms on run-time.
  • I was porting some code from C/C++ to .NET. I wanted mixed-mode implementation for desktop and safe implementation when running in restricted environment. This lead to the situation where I had 6 assemblies doing exactly the same thing: mixed-mode-x86, mixed-mode-x64, c++/cli-x86, c++/cli-x64, c#-unsafe-anycpu, c#-safe-anycpu and one additional assembly which was a façade which was redirecting all the calls to fastest one (depending on platform and trust level). I just didn't like 7 assemblies polluting the executable folder. With LibZ I was able to embed all of them in the façade and distribute it as single file, handling all platforms and trust levels.
  • The only problem with that is you don't have assemblies as files in folder, so they won't be picked up by MEF. Good news, LibZ allows to get MEF catalogue for LibZ files.

Comparing LibZ with similar products

You can find matrix of features which were important to me here.

If you don't like reading manuals

I strongly recommend reading the Documentation, but if you just don't like reading manuals, and you need the simplest case just install the tool run it using command-line:

libz inject-dll --assembly MyApplication.exe --include *.dll --move

Done.

Please note that this approach works for trivial applications only. If your application (or 3rd party libraries) use reflection, application domains, native DLLs you might need more "personalised" approach. Please refer to Scenarios.

More Repositories

1

K4os.Compression.LZ4

LZ4/LH4HC compression for .NET Standard 1.6/2.0 (formerly known as lz4net)
C#
667
star
2

lz4net

LZ4 - ultra fast compression algorithm - for all .NET platforms
C#
369
star
3

Hangfire.Storage.MySql

Hangfire storage adapter for MySql / fork of not maintained Hangfire.MySqlStorage
C#
42
star
4

K4os.Streams

Implementation for pooled in-memory streams for .NET
C#
39
star
5

stateful4k

State Machine Construction Kit for Kotlin
Kotlin
33
star
6

K4os.Hash.xxHash

XXHash for .NET Core 1.1/2.0 & .NET Standard 1.6/2.0
C#
24
star
7

SilesiaCorpus

Silesia compression corpus
16
star
8

K4os.Xpovoc

Χρόνος - simple job scheduler for .NET/Core
C#
11
star
9

Stateful

State Machine Construction Kit for .NET
C#
8
star
10

K4os.Text.BaseX

Base16/Base64/Base85/ShortGuid (quite fast) implementation for .NET/.NET Core
C#
7
star
11

TooMany

Docker inspired console application host for Windows
C#
6
star
12

EvoDistroLisa

Roger Johansson's (aka Roger Alsing) EvoLisa reborn (with F# and ZeroMQ)
F#
5
star
13

Proto.Persistence.AnySql

Persistence provider for Proto.Actor (potentially) handling any SQL database
C#
5
star
14

K4os.KnownTypes

KnownTypes registry to simplifying polymorphic serialization
C#
4
star
15

K4os.Hash.Crc

CRC32 implementation for .NET Standard 1.6/2.0
F#
3
star
16

fable-daedalus

Labyrinth generator with Fable and VirtualDom
F#
3
star
17

K4os.Data.TimSort

TimSort - "fastest general purpose sorting algorithm you never heard of" for .NET/Core
C#
2
star
18

K4os.Template.Orleans

Orleans template .NET project with Paket and Fake
C#
2
star
19

dotnetcambridge-dither

F# by example: playing with Bayer, Floyd and Steinberg
F#
1
star
20

Proto.Serialization.Json

Proto.Actor adapter for Newtonsoft.Json
F#
1
star
21

K4os.Template

Template solution for .NET core with Paket and Fake
C#
1
star
22

protosmuggler

Smuggles any payload in protobuf messages
F#
1
star
23

fable-bootstrap-virtualdom

Scaffolding for project with Fable, Bootstrap and VirtualDom
F#
1
star
24

K4os.Async.Batch

BatchBuilder for async operations
C#
1
star
25

kotlinjs-hexagen

Hexagonal maze generator with KotlinJS
Kotlin
1
star
26

many

Simple application to run multiple processes in one terminal window
F#
1
star
27

dnug-bloxorz

F#
1
star
28

K4os.CronEx

Cron expression parser and iterator
C#
1
star
29

K4os.Async.Toys

C#
1
star
30

K4os.Quarterback

Simple .NET implementation of in-process message broker on top of any DI container
C#
1
star