Sunday, February 6, 2011

Experiment with CLR’s Assembly Loader: “LoadFrom Context and its Probing Logic”

Recently, while reading two well-known CLR-related books: Advanced .NET Debugging and CLR via C# I found an interesting discrepancy. More precisely, I was reading the chapters related to CLR’s Assembly Loader (Fusion). The exact subject was the probing logic that Fusion uses when loading an assembly via LoadFrom context.

The first book says that when we load an assembly by using LoadFrom context, loader doesn’t use any probing logic and just tries to load the assembly from the specified location. The second book states that loader will still try to load the assembly from GAC if the assembly with the same identity exists there.

So I decided to try it myself and see which of these two is correct.

First I wrote a very simple .cs file:

MyAssembly.cs

using System;
using System.Reflection;

[assembly: AssemblyTitle("MyAssembly")]
[assembly: AssemblyVersion("1.2.3.4")]

namespace MyAssembly.MyNamespace
{
    public static class MyClass
    {
        public static void MyMethod()
        {
            Console.WriteLine("MyMethod()");
        }
    }
}

And created an assembly called MyAssembly.dll with the following commands:

sn -k key.snk
csc /t:library /keyfile:key.snk MyAssembly.cs

Then, I wrote a simple program that loads the assembly by using LoadFrom context.

Program.cs:

using System;
using System.Reflection;

namespace Experiment
{
    public class Program
    {
        public static void Main()
        {
            Assembly.LoadFrom("MyAssembly.dll").GetType("MyAssembly.MyNamespace.MyClass").GetMethod("MyMethod").Invoke(null, null);

            Console.WriteLine("Press any key to quit.");
            Console.ReadKey(true);
        }
    }
}

Then I compiled the program with:

csc Program.cs

and installed MyAssembly.dll to GAC (the assembly was already in the same folder as the program).

gacutil /i MyAssembly.dll

Finally, I started the program under WinDbg and listed loaded modules:

> lmf

start             end                 module name
00000000`00ba0000 00000000`00ba8000   Program  C:\Experiment\Program.exe
00000000`75630000 00000000`75638000   MyAssembly
C:\windows\Microsoft.Net\assembly\GAC_MSIL\MyAssembly\v4.0_1.2.3.4__0e23280d1783e3a4\MyAssembly.dll
...

As you can see, the assembly was loaded from GAC, not from the private path C:\Experiment\MyAssembly.dll.

Now we can formulate the more accurate description of LoadFrom context’s probing logic. Assembly Loader first reads the identity of the assembly at given location and then tries to find the assembly with the same identity in the GAC. If that fails, assembly will be loaded from the given file.

2 comments:

vipin said...

gr8 stuff thanks for sharing ur knowledge
http://soft-engineering.blogspot.com

Anonymous said...

Engineering is a great profession. There is the satisfaction of watching a figment of the imagination emerge through the aid of science to a plan on paper. Then it moves to realisation in stone or metal or energy. Then it brings homes to men or women. Then it elevates the standard of living and adds to the comforts of life. This is the engineer's high privilege.
Job oppurnity for nigerian peopole as well as international people, Offshore Engineering Jobs opportunity