Introduction
Today, I would like to cover a simple yet advanced topic: How to create dynamic assemblies and how to run dynamic code.
First, the basics (as usual)….
Assemblies
Assemblies form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions for a .NET-based application. Assemblies take the form of an executable (.exe) file or dynamic link library (.dll) file, and are the building blocks of the .NET Framework. They provide the common language runtime with the information it needs to be aware of type implementations. You can think of an assembly as a collection of types and resources that form a logical unit of functionality and are built to work together. For more information about assemblies, read here.
System.Reflection Namespace
The System.Reflection namespace contains types that retrieve information about modules, members, assemblies, parameters, and other entities in managed code by examining their metadata. These types also can be used to manipulate instances of loaded types. Here is more information on the System.Reflection Namespace.
System.Reflection.Emit Namespace
The System.Reflection.Emit namespace contains classes that allow a compiler or tool to emit metadata and Microsoft intermediate language (MSIL) and optionally generate a PE file on disk. The primary clients of these classes are script engines and compilers. Here is more information about the System.Reflection.Emit namespace
AssemblyName Class
Describes an assembly’s unique identity in full. Here is more information about the AssemblyName class.
AppDomain Class
Represents an application domain, which is an isolated environment where applications execute. This class cannot be inherited. Here is more information on the AppDomain class.
AssemblyBuilder Class
Defines and represents a dynamic assembly. Here is more information about the AssemblyBuilder class.
ModuleBuilder Class
Defines and represents a module in a dynamic assembly. Here is more information covering the ModuleBuider class.
TypeBuilder Class
Defines and creates new instances of classes during run time. Here is more information concerning the TypeBuilder class.
Our Project
Create a new Console Application and add the following code to the Module that has been created.
Imports System.Reflection Imports System.Reflection.Emit Class Program Public Shared Sub Main(ByVal args() As String) ' Create an Assembly Name Dim strANName As AssemblyName = New AssemblyName strANName.Name = "DemoAssembly" strANName.Version = New Version("1.0.0.0") ' Get the AppDomain to put our assembly in Dim adDomain As AppDomain = AppDomain.CurrentDomain ' Create the Assembly Dim assemBldr As AssemblyBuilder = _ adDomain.DefineDynamicAssembly(strANName, _ AssemblyBuilderAccess.ReflectionOnly) ' Define a module to hold our type Dim mbBuilder As ModuleBuilder = _ assemBldr.DefineDynamicModule("TestModule", _ "TestAssembly.dll") ' Create a new type Dim tbCar As TypeBuilder = _ mbBuilder.DefineType("Car", TypeAttributes.Public) ' Display the new Type Dim tCar As Type = tbCar.CreateType Console.WriteLine(tCar.FullName) For Each m As MemberInfo In tCar.GetMembers Console.WriteLine(" Member ({0}): {1}", _ m.MemberType, m.Name) Next Console.Read() End Sub End Class
I added the necessary Reflection namespaces to be able to work on the inner-workings of assemblies. Also, I created a dynamic Assembly and set the Assembly’s Name and Version properties. An AppDomain object is created to determine the domain in which the assembly has to be run.
Gradually, with the help of AssemblyBuilder, ModuleBuilder, and TypeBuilder the Assembly gets built. Lastly, the information of the new Assembly gets displayed, as shown in Figure 1.
Figure 1: Assembly
Conclusion
Assemblies are very powerful and useful, as you learned from working through this article. Until next time, cheers!