The death of multi-file assemblies (hopefully)

Now that Whidbey features can be freely talked about, I can mention my personal not-directly-C# feature: netmodule linking.  Basically due to some hard work by the C/C++ compiler and linker team, any tool that can produce managed netmodules(/target:module in C# abd VB land) can be linked into a single-file assembly by the linker!  You can now have a single file assembly witc, VB, C#, C++, and even native code all in one file!  Theoretically you can even link classic static .LIBs into your brand new C# assembly (although I’ve never tried that specifically).

The big down side is that there is no way to do most of this inside the C# project system inside the IDE. The XMake team (is that’s what it’s still called? they change names faster than a chameleon changes colors), tells me that their extensible make files and builds rules should allow this, but I’m not sure how that would interact with the IDE’s projects.  I have heard that the C/C++ project system works decently when only small amounts of code are written in another language.

The main reason there’s little to no IDE support is that the powers that be claim that the majority of C# users don’t want or need to do this kind of stuff (they even have some data to back that up).  So if this a useful feature, just make sure you’re not the silent majority…


Comments (11)

  1. Is this similar to ILMerge? Or have I totally missed the point?

  2. Grant says:

    Yes, somewhat. ILMerge was more of a back-door hack. This allows linking of pure IL images with non-pure code. And most importantly it is supported!

  3. Excellent – the lack of a linker has always been one of the big gripes of C++ coders…now I wonder if it’ll allow the merging in of Framework modules to build single file Exes for non-.NET-installed machines, now THAT would be cool!

  4. Grant says:

    I’m personally torn on the notion of statically linking in the runtime. Most people don’t want to statically link in gdi32.dll, they perfer to dynamically link it in from the OS. The CLR should be thought of as part of the OS (it already ships with Server 2003).

    You have to be really careful with the distinction between modules and assemblies. Nobody should ever ship modules because they are not directly referencable, nor do they have any versioning capabilities. Assemblies do, but because of that you run into identity issues.

    Specifically if such a linker existed, the runtime would see each definition of System.Windows.Forms.Form that was statically linked into different applications as totally different types. This can really burn people when they try and interoperate with anything else (any other assembly, remoting, Web services, etc.).

  5. True, and the ideal is that the .NET framework is installed as part of the OS – however that is just not the case at the moment – and it’s a major limiting factor in deploying .NET applications to run on the desktop – since you can’t be certain they’ll have it installed and the runtime is 20MB+ – which pretty much rules it out for any dial-up only user. So as i say, the ideal is not linking, but the option would help uptake in the short-medium term.

  6. Luc Cluitmans says:


    "The main reason there’s little to no IDE support is that the powers that be claim that the majority of C# users don’t want or need to do this kind of stuff (they even have some data to back that up). So if this a useful feature, just make sure you’re not the silent majority…"

    What??? Not useful??? I pass all of my code through ILMerge (or more correctly: through a wrapper that merges the exe with all DLLs in the build directory, with an option to exclude any DLLs that must not be merged).

    Let me provide some background: most applications I write are console applications for converting, filtering, processing data. I work in a research institute and the group I work for does lots of signal processing jobs. I end up writing lots of tools for converting data collected by custom data acquisition hardware into something that can be used by standard signal analysis/processing tools, such as Matlab or SPSS. The tasks tend to have many parts in common, so I have built up a collection of libraries for doing things like commandline argument parsing, reading the file formats we commonly use, writing those formats, and various processing and filtering steps. Most of these libraries are written in C#, with one or two in C++.

    So, when VS builds those applications they appear as a smallish executable and a big collection of DLLs. When ‘deploying’ those tools (that is: put them in a shared network drive where the people using the tools can copy them from) I dont want all those DLLs there. I want ‘COPY’ deployment, not ‘XCOPY’ deployment… Apart from the libraries written in C++, ILMerge allows me to achieve this goal: I simply ILMerge the executable with the DLLs it was built and tested with (as a post-build step). This saves me lots of deployment headaches. Having an ‘improved’ version of ILMerge built right into VS would be highly appreciated…

    Note that I am not referring to linking in any parts of the system or the .Net framework. I only want to link in my own homebrew libraries. In other words: what I really want is static libraries in .NET…

  7. pM says:

    It looks like this is something like thinstall


  8. Ryan Lamansky (Kardax) says:

    I think this is a great feature. IDE integration would be very helpful, of course 🙂

    If the compilers had dead code removal, this could be used to reduce the size of the deployment, especially with large projects using many libraries. This could also reduce app startup times.

    Statically linking the whole framework (dead code removal would be critical here) would be great. With the ongoing longhorn delays, the size of the framework is the biggest barrier to desktop deployment of a .NET app… lifting this would be very helpful.

  9. Hi Grant,

    This is a great feature. I see it most beneficial if it does dead-code removal as mentioned in other comments. This could reduce the download size of Thinstall-created EXEs, right now the smallest .NET EXE (including framework) I’ve created is 2.5MB – and much of mscorlib.dll could probably be stripped out dropping this down to almost 2MB by using this feature. Programs that use more code than a hello world would benefit even more from dead-code removal.

    I don’t know if you’ve seen Thinstall yet… It links everything into a single EXE (managed, unmanaged, DLLs, OCXs, data files, security settings, .NET Framework, virtual registry settings, etc). You end up with a single EXE file that runs on a clean install of Windows from CDROM or download link.). The next major version will compile all byte code into native code while still remaining 100% compatible with reflection (to lock-down any chance of decompilation, and speed up loadtime slightly). Worth taking a look at… We’ll support Whidbey as soon as it’s publicly released. 🙂


    btw, I just stumbled across this blog by accident – so if you care to respond, email is better. Keep up the good work!

  10. It’s been quite a while that I wondered why the hell this feature isn’t built into the IDE.

    I’d love to be able to link a few projects into one assembly using the IDE.