Reflection in .NET

In one of my projects there was more than one visual studio solution and a requirement of the infrastructure team was to reduce the number of solutions to exactly 1.
The choice was either to create one solution once, or create a tool with which the solutions are used as input to create a single solution containing all solutions.

We decided to create a tool that builds a wspbuilder structure and copies the files to the correct positions. Why? Developers can keep developing using their usual structure and the requirement is met.

For those projects that were created using the SharePoint Extensions for Visual Studio there was another problem, because during the creation of a WSP, VSE manipulates certain references (GUIDs) in the describing xml-files.

To remedy this, we of course needed to resolve those refrences ourselves. For GUIDs that reference classes reflection needed to be used for resolution of the full qualified class name.

Using the methods Assembly.Load(string), Assembly.Load(AssemblyName) worked fine until I forgot to retract the deployed solution and renamed a class. The result was, that the wrong name was resolved and on deployment the right class was not found, because the wrong name was referenced.

The problem was – you might have guessed – the assembly that was reflected was the one in the Global Assembly Cache (GAC), not the one in my project folder (newer version) although the assembly was referenced using an absolute path string.

So I needed to change the reflection mechanism. There is a static method on Assembly called ReflectionOnlyLoad(string). It reflects the assembly at the correct position, but you cannot search for classes and methods (which you can do if you use one of the Load methods) until you also reflect the assemblies that are referenced (recursive).

The two bool-flags of an Assembly-object GlobalAssemblyCache and ReflectionOnly help you differentiate between the usual case (you reference an assembly and it is used, because no version is in the GAC) and the special case (the GAC assembly version is used instead of the real assembly).

So this is what I did to make it work:

...
Assembly assembly = Assembly.LoadFile(fullName);
if(myAssembly.GlobalAssemblyCache)
{
    myAssembly = Assembly.ReflectionOnlyLoadFrom(fullName);
}
...
...
AssemblyName[] names = myAssembly.GetReferencedAssemblies();	
 if (realAssembly.ReflectionOnly && names.Length > 0)
 { 
   foreach (AssemblyName assembly in names)
   {
     Assembly tmp = Assembly.Load(assembly.FullName);
     if(tmp.FullName != null)
     {
       Assembly.ReflectionOnlyLoad(tmp.FullName);
     }
     else
     {
       throw new Exception(
        "Could not load assembly " +
        "with assemblyName '" +
        assembly.FullName + 
        "' for reflection purposes of receiverClass '" +
        receiverClassGuid + "'.");
     }
   }
 }
...
Advertisements

One Response to Reflection in .NET

  1. Pingback: 15 Useful Tools for MOSS 2007 Development « SharePoint 2007 Hut

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: