Published:
16 Apr 2007
|
Abstract
This article examines the programmatic creation of a satellite assembly with the help of the AssemblyBuilder class and its methods. |
|
by Uday Denduluri
Feedback
|
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days):
34954/
47
|
|
|
Introduction |
An assembly is a basic building block for any application in
the .NET Framework. It is a fundamental unit of deployment, version control,
reuse, activation scoping, and security permissions. An assembly is a
collection of types and resources that are built to work together and form a
logical unit of functionality. An assembly provides the Common Language Runtime
(CLR) with the information it needs to be aware of type implementations. During
runtime, a type does not exist outside the context of an assembly.
Creating an Assembly programmatically is one of the commonly
unexplored features available to programmers. In some scenarios this may be a
very useful feature. We can also create an assembly and add resources to it. In
this article we focus on creating an assembly with a class and methods. Later
on we will view reflection. We can also use ILDASM for viewing the contents of
the assembly. Before we actually go about creating an assembly we need to
understand what the contents of the assembly are.
The contents of an assembly are
·
CIL – Common Intermediate Language (formerly MSIL - Microsoft
Intermediate Language)
·
Assembly Manifest – The Assembly Manifest has the information
like Name, Version number, Culture, Strong Name information, etc.
·
Type Metadata
·
Resources
|
Assembly creation |
The code shown in Listing 1 is to create an assembly
programmatically. The code written is written in the C# language. The purpose
of the code is to create an assembly with a class added to it. We also add a
method to the class and finally save the dynamic assembly to the local system.
Listing 1
AppDomain currentDomain = Thread.GetDomain();
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "Test";
myAssemblyName.Version = new Version(1, 0, 0, 0);
AssemblyBuilder builder = currentDomain.DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder ObjModuleBuilder = builder.DefineDynamicModule("MyModule");
ObjModuleBuilder.DefineType("ClassName",
TypeAttributes.Class).DefineMethod("MethodName",
MethodAttributes.Public, CallingConventions.Standard);
builder.Save("MyAssembly.dll");
The AssemblyBuilder class is completely responsible for the
creation of an assembly. An instance of the AssemblyBuilder class can be
created by the current AppDomain. The steps for creating the assembly are
listed below.
Step 1: Get the current application domain from the current thread.
Step 2: Create an object of the type AssemblyBuilder from
the current application domain.
Step 3: Create the module builder object from the
AssemblyBuilder.
Step 4: Create the different types, methods, etc. and add them
to the Module Builder.
Step 5: Save the builder to the local system.
The complete description of each and every class used is
illustrated in the next section.
|
Classes Used for Creating an Assembly |
Let us now understand the types used for creating the
Assembly. Let us understand each one of them in detail.
Type Name
|
Description
|
AssemblyBuilder
|
Defines and represents a dynamic assembly. A dynamic
assembly is an assembly that is created using the Reflection Emit APIs. The
dynamic modules in the assembly are saved when the dynamic assembly is saved
using the Save method.
An AssemblyBuilder object is created by the
DefineDynamicAssembly method of the AppDomain Class.
|
ModuleBuilder
|
Defines and represents a module. A ModuleBuilder instance
can be created by calling DefineDynamicModule
method of the AssemblyBuilder class.
|
TypeBuilder
|
Defines and creates new instances of classes during
runtime. This can be created by the CreateType Method of the ModuleBuilder
class
|
AppDomain
|
Represents an application domain, which is an isolated
environment where applications execute. We can create this by using the CreateDomain
method, but we need the current AppDomain instance. Hence, we take it from
the current thread in which the application is running.
|
AssemblyName
|
Describes an assembly's unique identity in full. The
AssemblyName object contains information about an assembly, which can be used
to bind to that assembly. An assembly's identity consists of the simple name,
version number, cryptographic key pair, and supported culture. We need to use
this instance to give the name of the assembly.
|
AssemblyBuilderAccess
|
Defines the access modes for a dynamic assembly. This is
an enumeration. The enumeration values are as follows ReflectionOnly – The
dynamic assembly is loaded into the reflection-only context and cannot be
executed.
Run - The dynamic assembly can be executed but not saved.
RunAndSave – The dynamic assembly can be executed and
saved.
Save – The dynamic assembly can be saved but not executed.
|
|
Overview of ILDASM |
Intermediate Language Disassembler (ILDASM) is a utility
which loads the assembly and shows the contents of the Assembly. Let us create
an assembly and view the contents through ILDASM. This will help us to
understand how ILDASM displays the contents of the assembly.
We have created a namespace with the name Namespace1 and a
class with class1. The class has a single method, Method1, which is a void
method. We can view the created assembly using this tool.
Figure 1
|
Difference between Assembly and Satellite Assembly |
The Common Language Runtime (CLR) differentiates an assembly
from a satellite assembly by an attribute called the "AssemblyCultureAttribute".
A regular assembly contains code and the neutral culture's resources. A
satellite assembly contains only resources for a particular culture, as in
[assembly: AssemblyCultureAttribute ("en-US")]. Putting this
attribute on an assembly and using something other than the empty string
("") for the culture name will make this assembly a satellite
assembly rather than a regular assembly that contains executable code. Labeling
a traditional code library with this attribute will break it, because no other
code will be able to find the library's entry points at runtime. We have a
culture attribute in the Global Assembly Cache (GAC). If we open it and see, we
find that it does not have a value for a normal assembly and has the culture
name shown for the satellite assembly. This can be stated as the vital
difference between an assembly and a satellite assembly.
|
Conclusion |
Assemblies are a fundamental part of programming with the
.NET Framework. An assembly performs the following functions; contains code
that the common language runtime executes, forms a security boundary, acts as
the unit at which permissions are requested and granted, forms a type boundary,
forms a reference scope boundary, forms a version boundary, and forms a
deployment unit. Creating an assembly can be done programmatically, and that creation
of an assembly is done with the help of various classes like the
AssemblyBuilder, ModuleBuilder, AppDomain, AssemblyName, etc.
The compiler differentiates an assembly from a satellite
assembly by an attribute called AssemblyCultureAttribute. This attribute will
be filled with the appropriate value to identify the assembly as a normal
assembly or a satellite assembly.
|
References |
|
|
|
User Comments
Title:
no explantion
Name:
divys
Date:
2012-10-03 2:13:12 AM
Comment:
hi where is the coding part
|
Title:
method and purpose for creating assemblies
Name:
alice
Date:
2010-07-26 8:18:31 AM
Comment:
can u elaborate more on my title i dnt understand what should be written pliz
|
Title:
Nice
Name:
sandip
Date:
2010-07-13 5:32:38 AM
Comment:
Good, its good information
|
Title:
Hum Tum
Name:
Nitin Tiwari
Date:
2007-09-22 4:49:08 AM
Comment:
very Nice description....fine
|
|
|
|