C# – extern alias, and ILMerge’d assemblies

Sup­pose you want to merge an assem­bly A (AssemblyA.dll) with anoth­er assem­bly B (AssemblyB.dll) with ILMerge into a merged assem­bly (Merged.dll), and every­thing works fine until the user of your merged assem­bly also ref­er­ences that AssemblyB.dll, at which point that user will get Ambigu­ous ref­er­ence errors for any ref­er­ence to types defined in assem­bly B, for exam­ple:

image image

Under­stand­ably the com­pil­er is not hap­py here because it finds dupli­cat­ed def­i­n­i­tions for TypeB under the same name­space in the two ver­sions of the assem­bly B (the one ref­er­enced in the user’s project and the one that’s merged with assem­bly A).

So how do we get out of this unholy mess?

 

Well, there’s this lit­tle known fea­ture in .Net called extern alias which allows you to give ref­er­enced assem­blies an alias via that lit­tle Alias­es prop­er­ty in the Prop­er­ties win­dow for any ref­er­enced libraries (one I’m sure we have all seen count­less times and won­dered what it means).

By default the alias for an assem­bly is ‘glob­al’, which just means glob­al name­space, but you can change it via the Visu­al Stu­dio prop­er­ties win­dow or via com­mand line options to CSC.exe:

imageimage

Now the types defined in the Merged.dll assem­bly will fall under the Merged name­space and to access them you need to first add a line to your code:

extern alias Merged;

and then any­where you’re ref­er­enc­ing types from the Merged assem­bly you need to pre­fix it with Merged:: like the fol­low­ing.

image

You might also want to give Assem­blyB an alias just to remove any rea­son­able doubt which assem­bly a type comes from when­ev­er you ref­er­ence a type defined in Assem­blyB.

 

Whilst this is a way to get you out of a tight spot, it’s far from a clean solu­tion, and as @BjoernRochel said below, a good gen­er­al advice is to not merge assem­blies that you do not own to begin with:

image