Using ILmerge to Ease DLL Configuration Woes

The problem we have is that a significant portion of our codebase was written with the idea that the whole process will be using the same configuration data. This has worked pretty well for many years, but today we wanted to set up one of our projects to talk to a different database than the other projects in our solution. This problem is compounded because the connection string is stored in our standard configuration data. We also never pass this data anywhere as all our code connects to the database by going through specific utility functions/classes in our code base. Because both of the child projects interact with codebase and just link it in, there was no easy way we could come up with to alter the configuration of just one of the DLLs without altering the config for all projects.

Our solution makes use of the ILMerge tool from Microsoft. This tool is useful for combining many .Net assemblies and executables into a single assembly/executable. How this helps us solve our problem is that it supports a couple neat command line arguments. (ILmerge can also be run programmatically and as a nant task.) By using /internalize, we can completely absorb all of the merged in binaries, thereby not exposing them to anything that links to our library. (This is important because our goal is to internalize our code base which everything links to). Now by compiling in our configuration data (resx files), we get an assembly that while using our codebase internally, only looks at its internal configuration data, rather than the configuration shared by the rest of the application.

The command line used to accomplish this:

ilmerge /internalize /allowDup /out:Merged.dll ClassLibrary1.dll Codebase.dll

Some interesting notes. While the internalized binary reports its type as having the same name as the dll, when comparing whether the Types are ==, it returns false (which makes sense, otherwise it would be linked to duplicate type names.

C# 3.0 Feature Break Down

These are the new language features that I found being talked about;

  • Better Type Inferencing including the use of “var’ key word which macro-ishly rewrites to the type of object you assign to it. This is also the case with Arrays which now do not need explicit type declarations
    • var x = 42;
    • var arr = new[]{“This”, “is”, “a”, “string”, “array”};
  • Keyword Arguments in Constructors
    • new Point( X = 3, Y = 4)
    • X, and Y have a syntax to declare them similar to public accessors
    • //Due to Better Type inferencing we can elide Point
      var r = new Rectangle {
      P1 = { X = 0, Y = 1 },
      P2 = { X = 2, Y = 3 }
      };
  • Seems to have anonymous types / classes with an easy syntax
    • var x = new (X = 3, Y = 4)
    • var p1 = new { Name = "Lawnmower", Price = 495.00 };
      var p2 = new { Name = "Shovel", Price = 26.95 };
      p1 = p2; //These are of the same anonymous type
  • Opening base classes to provide functionality (a bit, you still cannot get to non public members on that class.)
    • namespace Extender{
      public static class XMLUtil {
      public static string ToXML(this Point pt) {
      // stuff
      }
      }
      }
    • Notice that our first parameter must be a type definition for the object we are wanting to extend.

  • Lambda expressions which in C# 3.0 seem to be mostly better syntax for anonymous delegates with outer variable capture(sic). For some reason they thought that the ADwOVC were a little verbose for the task at hand, and were not quite enough like LISP lambdas.
    • x => x + 1 // Implicitly typed, expression body
    • x => { return x + 1; } // Implicitly typed, statement body
    • (int x) => x + 1 // Explicitly typed, expression body
    • (int x) => { return x + 1; } // Explicitly typed, statement body
    • (x, y) => x * y // Multiple parameters
    • () => Console.WriteLine() // No parameters(Yay Thunk!)
  • Query Expression / LINQ: This is a big, so I am only going to cover it briefly. The goal of this is to allow set processing language in your C# program. It will convert a “Query Expression” into a series of function calls that will operate on a set of data. There is a ton more information about this out on the web if it piques your interest.
    • from c in customers
      from o in c.Orders
      orderby o.Total descending
      select new { c.Name, o.OrderID, o.Total }
    • from c in customers
      join o in orders on c.CustomerID equals o.CustomerID
      join d in details on o.OrderID equals d.OrderID
      join p in products on d.ProductID equals p.ProductID
      select new { c.Name, o.OrderDate, p.ProductName }
  • Expression Trees (from the spec): permit lambda expressions to be represented as data structures instead of executable code. Expression trees are efficient in-memory data representations of lambda expressions and make the structure of the expression transparent and explicit. While this certainly sounds interesting I wish they would have spent more than a paragraph on it in the language spec. My guess is that this is mostly in there to support what LINQ is doing more than that this was intended for end user use much. It is possible though that this would allow for macros expressed as operations on an Expression Tree. It also seems to backdoor in runtime evaluation.

The final result is that C# 3 is still static all over the damn place, but hey… they are working on it. Maybe version 4 will have a regular old eval function (hehehe)

C# 3.0 Language Spec
Extremely long article that I skimmed through and stole an example out of

Also … I started this cool post war on reddit.