I just had a crash course in .NET assembly lazy loading due to this bug.
For a little background, I've ripped System.Core/LINQ out of Mono to use in .NET 2.0, since our users are still on Win2K and can't use .NET 3.5 until we finish upgrading them all to XP. I'm writing a new rules engine using CS-Script that's working great. The following code worked fine:
if(someCrapInvolvingTheOldRulesEngine)
{
// snipped
}
if(useNewRulesEngine)
{
InitializeNewRulesEngine();
}
I needed to rewrite the first if block, which would depend on the new rules engine, so I switched the order of the "if" blocks, and suddenly, the dynamic compilation fails and completely crashes my app, saying it can't find the namespace "Linq".
After pounding my head on the desk for 2 hours (not an effective debugging technique), an idea hit, which solved the problem, and clued me in as to what was happening. I added the following line:
if(useNewRulesEngine)
{
List<int> unused = (new[]{1,2,3}).ToList();
InitializeNewRulesEngine();
}
if(someCrapInvolvingTheOldRulesEngine)
{
// snipped
}
That one additional line solved everything. Apparently, until I called that, System.Core wasn't loaded, and CS-Script couldn't find the assembly to reference. The "someCrapInvolvingTheOldRulesEngine" function in another assembly actually used System.Core, so it was loaded deep in that code. The old and new code have no dependencies on each other, so it was just baffling to me that simply switching the order of two unrelated "if" blocks could completely break my application.
I wound up moving the new line of code inside my RulesEngine initialization code with a "DO NOT REMOVE OR I WILL END YOU" comment, where it's going to have to stay until the users are able to use .NET 3.5 and can find the real System.Core in the GAC.