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.