February 25, 2021
Hot Topics:

Speed Up Your Reflection Processes

  • By Paul Kimmel
  • Send Email »
  • More Articles »

Defining the Dynamic Assembly

When you write an emitter, you have to include all of the elements, using Reflection.Emit, that you would include if you were writing the code in VB. This means you need an assembly, module, and methods with lines of code. Working from the big piece—the assembly—down to the little pieces—the lines of code.

The emitter in Listing 1 includes imports for System.IO, System.Reflection, System.Runtime.CompilerServices, and System.Reflection.Emit re-listed here with the first few lines of the emitter.

Listing 4: Starting your emitter.

Imports System.Reflection
Imports System.IO
Imports System.Runtime.CompilerServices
Imports System.Reflection.Emit

Module DynamicAssemblyCreator

   Public Sub CreateAssembly(Of T)(ByVal list As IEnumerable(Of T))

      Dim FunctionName As String = "Dump" + GetType(T).Name

      Dim name As AssemblyName = New AssemblyName()
      name.Name = GetType(T).Name + "Dumper"
      Dim domain As AppDomain = System.Threading.Thread.GetDomain()
      Dim builder As AssemblyBuilder = _
         domain.DefineDynamicAssembly(name, _
      Dim moduleBuilder As ModuleBuilder = _
         builder.DefineDynamicModule(GetType(T).Name + _
         "Dumper.dll", True)
      Dim typeBuilder As TypeBuilder = _
         moduleBuilder.DefineType("MyType", _
         TypeAttributes.Public Or TypeAttributes.Class)


CreateAssembly accepts a List(Of T). When you see (Of T) or something similar, you know you are using generics. Generics means the algorithm includes everything but the type, with T representing the type. The caller provides the type.

The first step defines a unique function name. You will need only to call this method once for each type. Calling it with a list of Customer objects means you will get a unique method named DumpCustomer.

Next, an AssemblyName object is needed and the AssemblyName.Name property is defined. Assemblies run within the context of an AppDomain and use the current AppDomain for the dyanmic assembly. The AssemblyBuilder is the root class used to aggregate all of the elements of a dynamic assembly. The ModuleBuilder represents a module—not in the VB sense of a Midule—but as an item containing code elements. Within modules, you add things like literal Modules or Classes. Your TypeBuilder will contain a Public Class named MyType.

Defining the Method

Within modules and classes, you add methods (among other things). Methods are emitted using the MethodBuilder class. Are you beginning to see the pattern? To define a dynamic assembly, you add all of the traditional elements using a class; generally, the emitter class is the name of the thing you want to add with the suffix Builder.

Just as with writing VB code, you need to define modifiers like Public and Shared and parameters. Listing 5 contains the fragment that defines the dumper method.

Listing 5: Use a MethodBuilder as the locus for your lines of code—with Reflection.Emit, the lines of code are IL opcodes.

Dim methodBuilder As MethodBuilder = _
   typeBuilder.DefineMethod(FunctionName, _
   MethodAttributes.Static Or MethodAttributes.Public)

methodBuilder.SetParameters(GetType(IEnumerable(Of T)))
Dim parmBuilder As ParameterBuilder = _
   methodBuilder.DefineParameter( _
   1, ParameterAttributes.In, "list")

Listing 5 defines a method with the named defined by FunctionName as a Public Shared method with an IEnumerable(OF T) parameter.

Getting References to Methods the Emitter Uses

As is true with writing VB code, you will want to leverage the framework in your emitter. The way to do this is get the MethodInfo object using Reflection for the methods you emitter will need. Listing 6 contains local variable MethodInfo references to Console.WriteLine, System.String.Concat, IEnumerator.MoveNext, IEnumerable.GetEnumerator, and IEnumerator.get_Current. Current is actually a property, but at the MSIL level properties are actually methods with a get_ and set_ prefix.

Listing 6: Obtaining handles to methods the emitter will use.

' Some methods
Dim write As MethodInfo = _
   GetType(Console).GetMethod("WriteLine", _
   New Type() {GetType(String)})

Dim concat As MethodInfo = _
   GetType(System.String).GetMethod("Concat", _
   New Type() {GetType(String), GetType(String)})

Dim MoveNext As MethodInfo = _
   GetType(System.Collections.IEnumerator).GetMethod("MoveNext", _
   New Type() {})

Dim enumer As MethodInfo = _
   GetType(IEnumerable(Of T)).GetMethod("GetEnumerator", _
   New Type() {})

   Dim get_Current As MethodInfo = _

Page 3 of 5

This article was originally published on October 28, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date