Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET type definitions in merged assemblies (ILMerge)

I am merging several .NET assemblies using ILMerge including some 3rd party assemblies. Since doing so, I've experienced several errors that all boil down to the fact that type definitions are tied to the assembly they are defined in.

A simple example is the log4net config section definition in my App.config. It uses type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" which will not work since the log4net assembly does not exist once it has been merged into my merged assembly. Not a big deal though, I change the assembly name to my merged assembly and it works fine.

A slightly more complicated example is binary serialized types. My system uses binary serialization to send certain objects between processes. All of the serializable objects are defined in a common assembly that all of the other projects reference. I was using the default binary serialization, but it started failing when deserializing the objects with the error stating that it could not find the merged assembly that serialized the object. Again, not a big deal, I implemented a custom SerializationBinder that looks for the type in any loaded assembly, not just the one given.

The previous example got more complicated when the serialized type reference other serializable types. I've continued to run into more and more problems that are getting increasingly difficult to deal with.

The point I'm trying to get at here is that the .NET type system and ILMerge don't appear to play well together. Does anyone have any experience with how they have solved this problem? Is it possible to tell the .NET runtime that I don't care what assembly the type says it should be in, just look for it anywhere?

NOTE: Please do not reply asking why I'm merging assemblies, that is not the point of this question.

like image 374
Stefan Moser Avatar asked Nov 05 '09 18:11

Stefan Moser


1 Answers

Yes, there is a solution to this problem: Build modules instead of assemblies!

Compilers for .net have an option (/target:module for C# and VB) that builds a module instead of an assembly. Multiple modules can then be passed to the compiler and used to build the final assembly.

Of course, this all assumes that you've got the source to those 3rd party assemblies. If you can't get that, perhaps a .netmodule version of the 3rd party assembly can be procured from the 3rd party?

If that won't work, you've still got one last option. Obviously you're already disassembling a 3rd party assembly into IL. Strip out the assembly information from that IL file and use "ilasm /dll" to build a .netmodule which you should now be able to use just like any other .netmodule!

By using modules instead of assemblies you shouldn't have any more assembly-based issues.

True, we've solved your problem with ILMerge by not using ILMerge anymore, but isn't that really the best solution?

Hope it works for you, here's some handy linkage:
.netmodule instead of assembly
ILASM with .netmodules

(And here I was thinking that my experience with .netmodules would never be useful to anyone!)

like image 151
Task Avatar answered Sep 30 '22 19:09

Task