I somehow ran into the issue when I was working on an application that installs an assembly to GAC on demand (on click of a button), and tries to Assembly.Load it at the click of a next button or tries to invoke a method from that newly GAC-ed assembly, but fails. Problem and repro steps are below.
Problem and Repro Steps: Create a new class library similar to the following named FooGreet.dll and strong name it. Let’s drag it to the assembly folder later.
namespace FooGreet
{
public class Greeting
{
public string SayHello()
{
return "Hello";
}
}
}
Create a console application to load the above class library, similar to the following code.
namespace FooGreetCaller
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press Enter to load assembly..");
while (true)
{
string input = Console.ReadLine();
if (input == "q" || input == "Q")
break;
try
{
System.Reflection.Assembly.Load("FooGreet, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=3f330bcf59df56c9");
Console.WriteLine("Assembly load success.");
}
catch (Exception eX)
{
Console.WriteLine(eX.Message + Environment.NewLine + eX.StackTrace);
}
}
}
}
}
- Run the console applition: Run an instance of the console application. Try to load the FooGreet.dll, you will get an exception with “Could not load file or assembly….”, no matter how many times you load. Don’t close the console window.
- Install FooGreet.dll to GAC: Drag FooGreet.dll to GAC, on the same instance of the console application, try to load the FooGreet.dll again, you still get the same exception; which I call an anomaly because the FooGreet.dll is in the GAC, and the console application should have recognized it. Shouldn't it have?
- Run a second instance of the console application: Run a second instance of the console application. Try to load the FooGreet.dll, now the assembly is loaded fine.
- Uninstall FooGreet.dll from GAC: Go to GAC, uninstall FooGreet.dll. Try loading the FooGreet.dll again in the second instance of the console application. The assembly is loaded successfully. Ideally, Shouldn’t it have thrown an exception like “Could not load file or assembly….”?
Question: Questions are at step 2 and 4. And from the happenings at step 2 and step 4, it looks like when an application loads, it takes a snapshot of the GAC (at least with the default AppDomain, I haven't tried creating and loading a new AppDomain). Is this true?
(In my app, as a workaround, I restart the application after I register the particular assembly to GAC with
System.EnterpriseServices.Internal.Publish().GacInstall(targetAssemblyName);
I am on a WinForms app and I am doing the restart in the Form_Load which causes the Main Form to flash for a fraction of a second.. which I dont like)