Skip to content
jbevain edited this page Sep 14, 2010 · 5 revisions

The .net type system that you can manipulate through traditional Reflection erases the difference between a reference and a definition. It only provides you with resolved types, fields and methods. At the metadata level, and thus, at the Cecil level, we make a distinction between a reference and a definition.

They are both scoped per ModuleDefinition. So, in a ModuleDefinition, a definition is a metadata element defined in the module itself, and a reference is a metadata element defined in another module. For instance, if you have an assembly Foo.dll, which contains the type Foo.Bar. This type Foo.Bar exposes a method, Baz that returns a System.String.

If you load Foo.dll using Cecil, Foo.Bar will be a TypeDefinition, and the return type of the method Baz will be a TypeReference to System.String. System.String is defined in the assembly mscorlib.dll, which means that if you open mscorlib.dll with Cecil, there will be a System.String TypeDefinition in it.

The process of getting a definition from a reference is called resolving. All resolvable references in Cecil have Resolve method. For instance, let’s say you have loaded Foo.dll in Cecil, and that you want to Resolve the return type of the Baz method:


var module = ModuleDefinition.ReadModule ("Foo.dll");

var foo_bar = module.Types.First (t => t.FullName == "Foo.Bar");
var baz = foo_bar.Methods.First (m => m.Name == "Baz");

var string_reference = baz.ReturnType;

// resolve into a definition:

var string_definition = string_reference.Resolve ();
var corlib = string_definition.Module;

In this example, string_definition will be a TypeDefinition, and its module will be the ModuleDefinition for mscorlib.dll. To find the assembly that defines the reference, Cecil uses the IAssemblyResolver of the ModuleDefinition for Foo.dll. You can specify your own IAssemblyResolver when reading a ModuleDefinition, by default it will use Mono.Cecil.GlobalAssemblyResolver.Instance.

Clone this wiki locally