Chapter 12. Reflection

Reflection is the mechanism provided by the .NET Framework to allow you to inspect how a program is constructed. Using reflection, you can obtain information such as the name of an assembly and what other assemblies a given assembly imports. You can even dynamically call methods on a type in a given assembly. Reflection also allows you to create code dynamically and compile it to an in-memory assembly or to build a symbol table of type entries in an assembly. Reflection is a very powerful feature of the framework, and, as such, is guarded by the runtime, requiring the ReflectionPermission be granted to assemblies doing this type of work. “Code Access Security” has only two permission sets that give all reflection access by default: FullTrust and Everything. The LocalIntranet permission set allows for the ReflectionEmit privilege that allows for emitting metadata and creating assemblies, but not the TypeInformation privilege for inspecting other assemblies or the MemberAccess privilege for performing dynamic invocation of methods on types in assemblies. In this chapter, you will see how you can use reflection to dynamically invoke members on types, figure out all of the assemblies a given assembly is dependent on, and inspect assemblies for different types of information. Reflection is a great way to understand how things are put together in .NET; this chapter provides a starting point.

12.1. Listing Imported Assemblies

Problem

You need to determine each assembly imported by a particular assembly. This information can show you if this assembly is using one or more of your assemblies or if your assembly is using another specific assembly.

Solution

Use the Assembly.GetReferencedAssemblies method to obtain the imported assemblies of an assembly:

using System;
using System.Reflection;
using System.Collections.Specialized;

public static void BuildDependentAssemblyList(string path, 
                                                StringCollection assemblies)
{
    // maintain a list of assemblies the original one needs
    if(assemblies == null)
            assemblies = new StringCollection( );

    // have we already seen this one?
    if(assemblies.Contains(path)==true)
        return;

    Assembly asm = null;
    // look for common path delimiters in the string 
    // to see if it is a name or a path
    if((path.IndexOf(@"",0,path.Length)!=-1)||
        (path.IndexOf("/",0,path.Length)!=-1))
    {
        // load the assembly from a path
        asm = Assembly.LoadFrom(path);
    }
    else
    {
        // try as assembly name
        asm = Assembly.Load(path);
    }
    // add the assembly to the list
    if(asm != null)
    {
        assemblies.Add(path);
    }

    // get the referenced assemblies
    AssemblyName[] imports = asm.GetReferencedAssemblies( );
    // iterate
    foreach (AssemblyName asmName in imports)
    {
        // now recursively call this assembly to get the new modules 
        // it references
        BuildDependentAssemblyList(asmName.FullName,assemblies);
    }
}

This code fills a StringCollection containing the original assembly, all imported assemblies, and the dependent assemblies of the imported assemblies.

If you ran this method against the assembly C:CSharpRecipesinDebugCSharpRecipes.exe, you’d get the following dependency tree:

  C:CSharpRecipesinDebugCSharpRecipes.exe

  mscorlib, Version=1.0.5000.0, Culture=neutral, 
    PublicKeyToken=b77a5c561934e089

  System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

  System.Xml, Version=1.0.5000.0, Culture=neutral, 
    PublicKeyToken=b77a5c561934e089

  System.Runtime.Serialization.Formatters.Soap, Version=1.0.5000.0, 
    Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

  REGEX_Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

  FileIODenied, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

  FileIOPermitted, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Discussion

Obtaining the imported types in an assembly is useful in determining what assemblies another assembly is using. This knowledge can greatly aid in learning to use a new assembly. This method can also help determine dependencies between assemblies for shipping purposes.

The GetReferencedAssemblies method of the System.Reflection.Assembly class obtains a list of all the imported assemblies. This method accepts no parameters and returns an array of AssemblyName objects instead of an array of Types. The AssemblyName type is made up of members that allow access to the information about an assembly, such as the name, version, culture information, public/private key pairs, and other data.

Note that this method does not account for assemblies loaded using the Assembly.Load* methods, as it is only inspecting for compile-time references.

See Also

See the “Assembly Class” topic in the MSDN documentation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.31.163