Saturday, 16 July 2011

Tutorials on .Net Assembly

What is a .Net Assembly?
The .NET assembly is the standard for components developed with the Microsoft.NET. Dot NET assemblies may or may not be executable, i.e., they might exist as the executable (.exe) file or dynamic link library (DLL) file. All the .NET assemblies contain the definition of types, versioning information for the type, meta-data, and manifest.

There are two kinds of assemblies in .NET; 

Private and shared 

Private assemblies are simple and copied with each calling assemblies in the calling assemblies folder. 

Shared assemblies (also called strong named assemblies) are copied to a single location (usually the Global assembly cache). For all calling assemblies within the same application, the same copy of the shared assembly is used from its original location. Hence, shared assemblies are not copied in the private folders of each calling assembly. Each shared assembly has a four part name including its face name, version, public key token and culture information. The public key token and version information makes it almost impossible for two different assemblies with the same name or for two similar assemblies with different version to mix with each other.

An assembly can be a single file or it may consist of the multiple files. In case of multi-file, there is one master module containing the manifest while other assemblies exist as non-manifest modules. A module in .NET is a sub part of a multi-file .NET assembly. Assembly is one of the most interesting and extremely useful areas of .NET architecture along with reflections and attributes, but unfortunately very few people take interest in learning such theoretical looking topics. 

To create and sign an assembly with a strong name using the Assembly Linker:
At the command prompt, type the following command:

al /out:<assembly name> <module name> /keyfile:<file name>

In this command, assembly name is the name of the assembly to sign with a strong name, module name is the name of the code module used to create the assembly, and file name is the name of the container or file that contains the key pair.
The following example signs the assembly MyAssembly.dll with a strong name using the key file sgKey.snk.

al /out:MyAssembly.dll MyModule.netmodule /keyfile:sgKey.snk

To sign an assembly with a strong name using attributes
In a code module, add the AssemblyKeyFileAttribute or the AssemblyKeyNameAttribute, specifying the name of the file or container that ontains the key pair to use when signing the assembly with a strong name.

The following code example uses the AssemblyKeyFileAttribute with a key file called keyfile.snk, located in the directory where the assembly is compiled.
 
[assembly:AssemblyKeyFileAttribute("keyfile.snk")]

Assembly Manifest
Every assembly, whether static or dynamic, contains a collection of data that describes how the elements in the assembly relate to each other. The assembly manifest contains this assembly metadata. An assembly manifest contains all the metadata needed to specify the assembly's version requirements and security identity, and all metadata needed to define the scope of the assembly and resolve references to resources and classes. The assembly manifest can be stored in either a PE file (an .exe or .dll) with Microsoft intermediate language (MSIL) code or in a standalone PE file that contains only assembly manifest information.
The following illustration shows the different ways the manifest can be stored.
Types of assemblies

For an assembly with one associated file, the manifest is incorporated into the PE file to form a single-file assembly. You can create a multifile assembly with a standalone manifest file or with the manifest incorporated into one of the PE files in the assembly.
Each assembly's manifest performs the following functions:
Enumerates the files that make up the assembly. Governs how references to the assembly's types and resources map to the files that contain their declarations and implementations.
Enumerates other assemblies on which the assembly depends. Provides a level of indirection between consumers of the assembly and the assembly's implementation details.
Renders the assembly self-describing.

Assembly Manifest Contents
The following table shows the information contained in the assembly manifest. The first four items — the assembly name, version number, culture, and strong name information — make up the assembly's identity.
Information
Description
Assembly name
A text string specifying the assembly's name.
Version number
A major and minor version number, and a revision and build number. The common language runtime uses these numbers to enforce version policy.
Culture
Information on the culture or language the assembly supports. This information should be used only to designate an assembly as a satellite assembly containing culture- or language-specific information. (An assembly with culture information is automatically assumed to be a satellite assembly.)
Strong name information
The public key from the publisher if the assembly has been given a strong name.
List of all files in the assembly
A hash of each file contained in the assembly and a file name. Note that all files that make up the assembly must be in the same directory as the file containing the assembly manifest.
Type reference information
Information used by the runtime to map a type reference to the file that contains its declaration and implementation. This is used for types that are exported from the assembly.
Information on referenced assemblies
A list of other assemblies that are statically referenced by the assembly. Each reference includes the dependent assembly's name, assembly metadata (version, culture, operating system, and so on), and public key, if the assembly is strong named.

What are the basic components of .NET platform?

The basic components of .NET platform (framework) are:  

  .Net Applications

  (Win Forms, Web Applications, Web Services)
  Data(ADO.Net) and XML Library

  FrameWork Class Library(FCL)
 
  (IO,Streams,Sockets,Security,Reflection,UI)
  Common Language Runtime(CLR)

  (Debugger,Type Checker,JITer,GC)

  Operating System

  (Windows,Linux,UNIX,Macintosh,etc.,)


Common Language Runtime (CLR):
The most important part of the .NET Framework is the .Net Common Language Runtime (CLR) also called .Net Runtime in short. It is a framework layer that resides above the Operating System and handles/manages the execution of the .NET applications. Our .Net programs don't directly communicate with the Operating System but through CLR. 

MSIL (Microsoft Intermediate Language) Code:
When we compile our .Net Program using any .Net compliant language like (C#, VB.NET, C++.NET) it does not get converted into the executable binary code but to an intermediate code, called MSIL or IL in short, understandable by CLR. MSIL is an OS and H/w independent code. When the program needs to be executed, this MSIL or intermediate code is converted to binary executable code, called native code. The presence of IL makes it possible the Cross Language Relationship as all the .Net compliant languages produce the similar standard IL code. 

Just In Time Compilers (JITers):
When our IL compiled code needs to be executed, CLR invokes JIT compilers which compile the IL code to native executable code (.exe or .dll) for the specific machine and OS.

JITers in many ways are different from traditional compilers as they, as their name suggests, compile the IL to native code only when desired e.g., when a function is called, IL of function's body is converted to native code; just in time of need. So, the part of code that is not used by particular run is not converted to native code. If some IL code is converted to native code then the next time when its needed to be used, the CLR uses the same copy without re-compiling. So, if a program runs for sometime, then it won't have any just in time performance penalty. As JITers are aware of processor and OS exactly at runtime, they can optimize the code extremely efficiently resulting in very robust applications. Also, since JITer knows the exact current state of executable code, they can also optimize the code by in-lining small function calls (like replacing body of small function when it’s called in a loop, saving the function call time). Although, Microsoft stated that C# and .Net are not competing with languages like C++ in efficiency, speed of execution, JITers can make your code even faster than C++ code in some cases when program is run over extended period of time (like web-servers). 

Framework Class Library (FCL):
.NET Framework provides huge set of Framework (or Base) Class Library (FCL) for common, usual tasks. FCL contains thousands of classes to provide the access to Windows API and common functions like String Manipulation, Common Data Structures, IO, Streams, Threads, Security, Network Programming, Windows Programming, Web Programming, Data Access, etc. It is simply the largest standard library ever shipped with any development environment or programming language. The best part of this library is they follow extremely efficient OO design (design patterns) making their access and use very simple and predictable. You can use the classes in FCL in your program just as you use any other class and can even apply inheritance and polymorphism on these. 

Common Language Specification (CLS):
Earlier we used the term '.NET Compliant Language' and stated that all the .NET compliant languages can make use of CLR and FCL. But what makes a language '.NET compliant language'? The answer is Common Language Specification (CLS). Microsoft has released a small set of specification that each language should meet to qualify as a .NET Compliant Language. As IL is a very rich language, it is not necessary for a language to implement all the IL functionality, rather it meets the small subset of it, CLS, to qualify as a .NET compliant language, which is the reason why so many languages (procedural and OO) are now running under .Net umbrella. CLS basically addresses to language design issues and lays certain standards like there should be no global function declaration, no pointers, no multiple inheritance and things like that. The important point to note here is that if you keep your code within CLS boundary, your code is guaranteed to be usable in any other .Net language.

Common Type System (CTS):
.NET also defines a Common Type System (CTS). Like CLS, CTS is also a set of standards. CTS define the basic data types that IL understands. Each .NET compliant language should map its data types to these standard data types. This makes it possible for the 2 languages to communicate with each other by passing/receiving parameters to/from each other. For example, CTS defines a type Int32, an integral data type of 32 bits (4 bytes) which is mapped by C# through int and VB.Net through its Integer data type. 

Garbage Collector (GC):
Garbage collection is a CLR feature which automatically manages memory. Programmers forget to release the objects while coding ..... laziness ( Remember in VB6 where one of the good practices is to set object to nothing).CLR automatically releases objects when they are no longer referenced and in use.CLR runs on non-deterministic to see the unused objects and cleans them.

CLR also contains Garbage Collector (GC) which runs in a low-priority thread and checks for un-referenced dynamically allocated memory space. If it finds some data that is no more referenced by any variable/reference, it re-claims it and returns the occupied memory back to the Operating System; so that it can be used by other programs as necessary. The presence of standard Garbage Collector frees the programmer from keeping track of dangling data.


Posted By: Mr. Palash Paul

1 comment: