views:

995

answers:

4

I am wondering what are the heuristics when creating releases of libraries to be included in other projects in relation to dependencies and if I should include them or not.

My problem is the following:

I have a CommonUtilities library that provides as the name implies a set of utilities that can be used in more than one place. Dependencies of CommonUtilities include log4net.dll (the logging framework) and Oracle.DataAccess.dll (database driver).

I have another project called MyProject that I want to include CommonUtilities in. MyProject also depends on Oracle.DataAccess.

If I use ILMerge and merge CommonUtilities into a single assembly CommonUtilities.dll and reference that from MyProject everything compiles but I am sure I should explicitly reference Oracle.DataAccess from MyProject as it is a dependency and not use the assembly merged into CU. Adding a reference to Oracle.DataAccess as well results in ambiguous using statements as there are two Oracle.DataAccess assemblies referenced.

Using ILMerge /Internalize in my case results in compile errors as types from the internalized Oracle.DataAccess assembly are being returned from CommonUtilities and as they are marked internal MyProject does not recognize the type returned.

The only way to make this work is simply to not merge this particular assembly (Oracle.DataAccess) into CommonUtilities and only reference that from MyProject. This in turn creates a new problem: Which Oracle.DataAccess.dll should I reference - the dependency distributed with CommonUtils or not?

Are there other ways to go about all this?

A: 

I suppose there might be some advantage with regards to keeping a bunch of localized assemblies in one (which, I am not even sure you can do)

I would not merge libraries from other vendors - because they often have their own licensing, and updating them would require you to redistribute a new version of your code.

Merging your own libraries may be advantageous if you have many libraries to keep the directory neat, or make sure that some code will ALWAYS be with the main executing assembly.

I think ILMerge does better with libraries being merged into an EXE, so that you have one file instead of many.

Andrew Theken
+1  A: 

We don't merge libraries at all. I can't see much advantage in merging libraries together that you can't get but just building them in one assembly in the first place.

I can see the benefits in merging libraries with an EXE. That could be real handy. The problem with merging libraries together is that they may have different versions of a dependancy in your EXE and that can make for uncomfortable bedfellows.

I don't think merging dlls together could be considered best practice except when you are merging them into an EXE to present a single file instead of multiple files.

Brody
+1  A: 

The short, easy version:

Every reference within one process to a given Assembly should reference the same version.

If you don't, you might get into deep troubles because one part of the app cannot talk to another due to version mismatch.

Even with "really private" stuff like log4net you might miss out on possibilities for shared configuration space, like using a common root logger for all parts of the app. Of course, the final call in this case is -- as always -- with the responsible developer.

See also this other question about ILMerge and 3rd party assemblies.

David Schmitt
A: 

The biggest reason we use ILMerge is to make our obfuscation step that much more difficult to reverse. By merging them together using the /internalize flag the obfuscator can then rename the public classes and methods that we merged into the parent assembly.

From IL merge Documentation: "[Internalize] controls whether types in assemblies other than the primary assembly have their visibility modified. When it is true, then all non-exempt types that are visible outside of their assembly have their visibility modified so that they are not visible from outside of the merged assembly"

If the assemblies are kept separate then the obfuscator won't rename them.

BTW Eazfuscator is awesome, and free: http://www.foss.kharkov.ua/g1/projects/eazfuscator/dotnet/Default.aspx