.NET FRAMEWORK

MOREDOTNET  NOTES ON .NET 


 

HOME

.NET - is the Microsoft Web services strategy to connect information, people, systems, and devices through software. Integrated across the Microsoft platform, .NET technology provides the ability to quickly build, deploy, manage, and use connected, security-enhanced solutions with Web services. .NET-connected solutions enable businesses to integrate their systems more rapidly and in a more agile manner and help them realize the promise of information anytime, anywhere, on any device. (Source: http://www.microsoft.com/net/Basics.mspx )

Size of a .NET object - Minimum 12 bytes. 4 bytes for the table pointer, 4 bytes for the sync block, and 4 bytes or more for the datatypes in the class. Even if there is no data type in the class, the object will take 12 bytes, as per the CLR's functionality.

Programming Languages in .NET - C#, VB.NET, JS.NET, C++.NET

Versions of .NET - The final version of the 1.0 SDK & runtime were made publically available on 15 - Jan -2002. At the same time, the final version of Visual Studio.NET was made available to MSDN subscribers. .NET 1.1 was released in April 2003, with bugs fixed. .NET 2.0 was launched in October 2005 for MSDN subscribers, and officially released in Nov 2005. On - Jun - 2006, .NET 3.0 was launched. This version is called WinFX.

Operating systems support in .NET - The runtime supports Windows Server 2003, Windows XP, Windows 2000, NT4 SP6a and Windows ME/98. Windows 95 is not supported. Some parts of the framework do not work on all platforms - for example, ASP.NET is only supported on XP and Windows 2000/2003. Windows 98/ME cannot be used for development.

Update: All versions of Vista support .NET.

IIS is not supported on Windows XP Home Edition, and so cannot be used to host ASP.NET. However, the ASP.NET Web Matrix web server does run on XP Home.

.NET Compact Framework - is a version of .NET for mobile devices. They run Windows CE or Widows Mobile.

Mono - This version of .NET runs on Linux. Still not popular.

Tools for developing .NET applications :

The .NET Framework SDK is free and includes command-line compilers for C++, C#, and VB.NET and various other utilities to aid development.
SharpDevelop is a free IDE for C# and VB.NET.
Microsoft Visual Studio Express editions are cut-down versions of Visual Studio, for hobbyist or novice developers.    There are different versions for C#, VB, web development etc. Originally the plan was to charge $49, but MS has        decided to offer them as free downloads instead, at least until November 2006. Microsoft Visual Studio Standard 2005 is around $300, or $200 for the upgrade. Microsoft VIsual Studio Professional 2005 is around $800, or $550 for the upgrade. At the top end of the price range are the Microsoft Visual Studio Team Edition for Software Developers 2005 with MSDN Premium and Team Suite editions. Visual Web Developer Express is available as a free download.

CLI (Common Language Infrastructure) - is the definition of the fundamentals of the .NET framework. It is documented through ECMA (http://msdn.microsoft.com/netframework/ecma/).  The fundamentals include the  following:

*CTS (Common Type Specification)

*Metadata

* VES (Virtual Execution Environment)

* IL (Or MSIL) (Microsoft Intermediate Language)

* CLS (Common Language Specification)

CLR - Common Language Runtime -  It is the implementation of CLI. The core runtime engine in the Microsoft .NET Framework for executing applications. The common language runtime supplies managed code with services such as cross-language integration, code access security, object lifetime management, resouce management, type safety,   pre-emptive threading, metadata services (type reflection), and debugging and profiling support. The ASP.NET   Framework and Internet Explorer are examples of hosting CLR.

The CLR is a multi-language execution environment. There are currently over 15 compilers being built by Microsoft and other companies that produce code that will execute in the CLR.

The CLR is described as the "execution engine" of .NET. It's this CLR that manages the execution of programs. It provides the environment within which the programs run. The software version of .NET is actually the CLR version.

When the .NET program is compiled, the output of the compiler is not an executable file but a file that contains a special type of code called  the Microsoft Intermediate Language (MSIL). This MSIL defines a set of portable instructions that are independent of any specific CPU. It's the job of the CLR to translate this Intermediate code into a executable code when the program is executed making the program to run in any environment for which the CLR is  implemented. And that's how the .NET Framework achieves Portability. This MSIL is turned into executable code using a JIT (Just In Time) complier. The process goes like this, when .NET programs are executed, the CLR        activates the JIT complier. The JIT complier converts MSIL into native code on a demand basis as each part of the program is needed. Thus the program executes as a native code even though it is compiled into MSIL making the   program to run as fast as it would if it is compiled to native code but achieves the portability benefits of MSIL.

 

Class Libraries - Class library is the another major entity of the .NET Framework. This library gives the program access to runtime environment. The class library consists of lots of prewritten code that all the applications created in VB .NET and Visual Studio .NET will use. The code for all the elements like forms, controls and the rest in VB .NET applications actually comes from the class library.

Common Language Specification (CLS) - If we want the code which we write in a language to be used by programs in other languages then it should adhere to the Common Language Specification (CLS). The CLS describes a set of features that different languages have in common. The CLS includes a subset of Common Type System (CTS) which define the rules concerning data types and ensures that code is executed in a safe environment.

Common Type Specification(CTS) - The Common Type System (CTS) defines the rules concerning data types and ensures that code is executed in a safe environment. Since all .NET applications are converted to IL before execution all primitive data types are represented as .NET types. This means that, a VB Integer and a C# int are both represented      in IL code as System.Int32. Because both the languages use a common and interconvertible type system, it is possible    to transfer data between components and avoid time-consuming conversions.

Microsoft Intermediate Language(MSIL) - When compiling to managed code, the compiler translates your source code into Microsoft intermediate language (MSIL), which is a CPU-independent set of instructions that can be efficiently converted to native code. MSIL includes instructions for loading, storing, initializing, and calling methods on objects, as well as instructions for arithmetic and logical operations, control flow, direct memory access, exception handling, and  other operations. Before code can be run, MSIL must be converted to CPU-specific code, usually by a just-in-time (JIT) compiler. Because the common language runtime supplies one or more JIT compilers for each computer architecture it supports, the same set of MSIL can be JIT-compiled and run on any supported architecture.

When a compiler produces MSIL, it also produces metadata. Metadata describes the types in your code, including the definition of each type, the signatures of each type's members, the members that your code references, and other data  that the runtime uses at execution time. The MSIL and metadata are contained in a portable executable (PE) file that is based on and extends the published Microsoft PE and common object file format (COFF) used historically for executable content. This file format, which accommodates MSIL or native code as well as metadata, enables the operating system to recognize common language runtime images. The presence of metadata in the file along with the MSIL enables your code to describe itself, which means that there is no need for type libraries or Interface Definition Language (IDL). The runtime locates and extracts the metadata from the file as needed during execution.

Managed Code - The .NET framework provides lots of core runtime services to the programs that run within it. For example - security & exception handling. Such a code has a minimum level of information. It has metadata associated with it. Such a code is called Managed Code. VB.NET, C#, JS.NET code is managed by default. In order to make C++ code managed, we make use of managed extensions, which is nothing but a postfix _gc after the class name.

Managed Data - Data that is allocated & freed by the .NET runtime's Garbage collecter.

Managed Class - A class whose objects are managed by the CLR's garbage collector. In VC++.NET, classes are not managed. However, they can be managed using managed extentions. This is done using an _gc postfix. A managed    C++ class can inherit from VB.NET classes, C# classes, JS.NET classes. A managed class can inherit from only one class. .NET does'nt allow multiple inheritance in managed classes.

Reflection - The process of getting the metadata from modules/assemblies. When .NET code is compiled, metadata about the types defined in the modules is produced. These modules are in turn packaged as assemblied. The process   of accessing this metadata in called Reflection.

The namespace System.Reflection contains classes that can be used for interrogating the types for a module/assembly. We use reflection for examining data type sizes for marshalling across process & machine boundaries.

Reflection is also used for:

1) To dynamically invoke methods (using System.Type.InvokeMember)   2) To dynamically create types at runtime (using System.Reflection.Emit.TypeBuilder).

Assembly -  An assembly may be an exe, a dll, an application having an entry point, or a library. It may consist of one or more files. It represents a group of resources, type definitions, and implementation of these types. They may contain references to other assemblies. These resources, types & references are compacted in a block of data called manifest. The manifest is a part of the assembly, which makes it self-describing. Assemblies also increase security of code in .NET. An assembly maybe shared(public) or private.

An assembly may be created by building the class(the .vb or .cs file), thereby producing its DLL.

ILDASM - The contents of an assembly may be viewed using the ILDASM tool, that comes with the .NET SDK or the Visual Studio.NET.

Private Assembly - This type of assembly is used by a single application. It is stored in the application's directory or the applications sub-directory. There is no version constraint in a private assembly.

Shared Assembly (or Public Assembly) - A shared assembly has version constraint. It is stored in the Global Assembly Cache (GAC). GAC is a repository of shared assemblies maintained by the .NET runtime. The shared assemblies may be used by many applications. To make an assembly a shared assembly, it has to be strongly named.

In order to share an assembly with many applications, it must have a strong name.

In order to convert a private assembly to a shared assembly, i.e. to create a strongly named assembly, follow the steps below...

1) Create a strong key using the sn.exe tool. This is used to created a cryptographic key pair.  The key pair that is generated by the Strong Name tool can be kept in a file or we can store it our your local machine's Crytographic Service Provider (CSP). For this, goto the .NET command interpreter, and type the following...

    sn -k C:\samplekey.snk

This will create a strong key and save it to the location C:\samplekey.snk

2)  If the key is stored in a file, just like we have done above, we use the attribute AssemblyKeyFileAttribute. This belongs to the namespace System.Reflection.AssemblyKeyFileAttribute.

If the key was in the CSP, we would make use of System.Reflection.AssemblyKeyNameAttribute.

Go to the assemblyinfo.vb file of your project. Open this file. Make the following changes in this file...

<assembly: assemblykeyfileattribute("C:\samplekey.snk")>

We may write this in our code as well, like this...

Imports System.Reflection
<assembly: assemblykeyfileattribute("C:\samplekey.snk")>

Namespace StrongName
   Public class Sample
   End Class
End Namespace

3) Build your project. Your assembly is now strongly named.

Installing the Shared assembly in GAC...

Go to .NET command interpreter, use the tool gacutil.exe

Type the following...

gacutil /i sampleclass.dll To uninstall it, use... gacutil /u sampleclass.dll Visual Studio.NET provides a GUI tool for viewing all shared assemblies in the GAC.

Folder of GAC: C:\Windows\Assembly


Assembly Versioning - Each assembly (shared assembly) has a version. Its called the compatibility version.  There are 4 parts in the version, namely Major, Minor, Build, Version. If the first two parts are same, then two assemblies are compatible. If they are different, they are incompatible. If the third part is different, then the two assemblies may or may not be compatible. If only the fourth part is different, then they are surely compatible.  The version policy may be applied using the application's configuration file(.config file). Application Domain - An application domain is a process running on the .NET runtime. In a Win32 environment, the application domain can host several instances known as processes on the machine. An application domain may be destroyed, without affecting other processes, as each application domain is a separate process.  The host, which is the Windows shell, creates a new application domain for every application. For example, several instances of Internet Explorer may be running on a single PC.  Garbage Collection - Garbage collection is a heap-management strategy where a run-time component takes responsibility for managing the lifetime of the memory used by objects. This concept is not new to .NET - Java and many other languages/runtimes have used garbage collection for some time. The garbage collector runs periodically. It runs through a list of objects that are currently being referenced by an application. All objects that it does not find during this search are ready to be destroyed (using the finalize method) and hence free the memory. However, the runtime gets notified of the object that has been destroyed, only in the next round of the garbage collector's periodic cycle.

In the class System.GC, there is a method called collect( ). This forces the garbage collector to collect all unreferenced objects immediately, thereby giving the developer some control over the garbage collector.

There is a gcConcurrent setting that can be set through the applications's .config file. This specifies whether or  not the garbage collector performs its activities on a specified thread or not.

We can view the performance monitor to view the activities of the garbage collector.

IDisposable interface - We implement this interface to a class when we have to work with unmanaged types. For  example, an IntPtr member representing an operating system's file handler is actually unmanaged, and in order to   destroy it, we make use of the Dispose method by implementing the IDisposable interface. In this case, we override         the Finalize method. Note that we make use of Dispose method on those objects which have an uncertain life period,     and thus the garbage collector does not finalize them automatically.

We also make use of Dispose method while working with managed code, for example, an object os  System.IO.FileStream may have an uncertain life, and in order to dispose it, we use the dispose method. Such types of objects are not accessed by the Garbage Collector's Finalizer.

Serialization - The process of converting an object into a stream of bytes.This stream of bytes can be persisted. Deserialization is an opposite process, which involves converting a stream of bytes into an object. Serialization is used usually during remoting (while transporting objects) and to persist file objecst & database objects.

.NET provides 2 ways for serializtion 1) XmlSerializer and 2) BinaryFormatter/SoapFormatter

The XmlSerializer is used for Web Services. The BinaryFormatter & SoapFormatter is used for Remoting.

While using XmlSerializer, it is required that the target class has parameter less constructors, has public read-write properties and has fields that can be serialized. The XmlSerializer has good support for XML documents. It can be used to construct objects from existing XML documents. The XmlSerializer Enables us to serialize and   deserialize objects to an XML format.

SoapFormatter enables us to serialize & deserialize objects to SOAP format. They can serialize private and public fields of a class. The target class must be marked with the Serializable attribute. On deserialization, the constructor of the new object is not invoked. 

The BinaryFormatter has the same features as the SoapFormatter except that it formats data into binary format.

The BinaryForamatter (and the SoapFormatter) has two main methods. Serialize and Deserialize. To serialize an object, we pass an instance of the stream and the object to the Serialize method. To Deserialize an object, you pass an instance of a stream to the Deserialize method.

You can use the BinaryFormatter to serialize many, but not all, classes in the .NET Framework. For example, you can serialize ArrayLists, DataSets, and Arrays but not other objects, such as DataReaders or TextBox controls. To serialize a class, the class must have the Serializable attribute or implement the ISerializable interface.

Note that the XmlSerializer captures only the public members of the class, whereas the BinaryFormatter & the SoapFormatter captures both the public & private members of the class. The output using the   BinaryFormatter is quite compact, as the information is in binary format, whereas the XmlSerializer format is filled with XML tags.

See example below...

Imports System.IOImports System.Runtime.Serialization.Formatters.Binary

Dim colArrayList As ArrayListDim

objFileStream As FileStreamDim

objBinaryFormatter As BinaryFormattercolArrayList = New ArrayList()

colArrayList.Add( "Whisky")

colArrayList.Add( "Vodka")

colArrayList.Add( "Brandy")

objFileStream = New FileStream(MapPath("C:\myArrayList.data"), FileMode.Create)objBinaryFormatter = New BinaryFormatterobjBinaryFormatter.Serialize(objFileStream, colArrayList)objFileStream.Close()

Here we see that an instance of the file stream (objFileStream) and an instance of the object (colArrayList) is passed to the Serialize method of the BinaryFormatter object (objBinaryFormatter). We also end up creating a file by the name myArrayList.data on our hard-drive.In order to deserialize an object, see the code below…

Dim colArrayList As ArrayListDim objFileStream As FileStreamDim

objBinaryFormatter As BinaryFormatterDim strItem As String

objFileStream = New FileStream( MapPath("myArrayList.data"), FileMode.Open )

objBinaryFormatter = New BinaryFormattercolArrayList = CType( objBinaryFormatter.Deserialize( objFileStream ), ArrayList )

objFileStream.Close()

For Each strItem In colArrayList

  Response.Write( "<li>" & strItem )

Next

Here, CType takes in two parameters, the first parameter is the serialized object in the file stream format, and the second parameter is the desired type. Finally, the page iterates through all the elements of the ArrayList and displays the value of each element.

Example below shows how we can serialize a class to a database table... Imports System

Namespace myComponents

<serializable()> Public Class UserInfo
  Public Username As String
  Public Password As String
  Public Email As String
End Class

End Namespace The class above contains 3 public properties. Using the serializable attribute with this class means we can serialize the class. To use this class, we have to compile it from the command line (or VS.NET). We use the following command... vbc /t:Library UserInfo.vb
Next, copy the compiled class, UserInfo.dll, to our application /bin directory. Placing the UserInfo.dll file in our /bin directory exposes the class to your ASP.NET application. Next, we create a table in our SQL Server...

  CREATE TABLE UserList (
  user_id INT NOT NULL IDENTITY,
  username VARCHAR( 50 ),
  userinfo Image )
For further code  CLICK HERE

Xml Serializer does not serialize instances of classes like Hashtable which implement the IDictionary interface.

Attributes - Is a kind of property attached with a class. It allows some data to be attached to a class or method. This data becomes part of the metadata for the class, and (like other class metadata) can be accessed via reflection. An example of a metadata attribute is [serializable], which can be attached to a class and means that instances of the class can be serialized.

 [Serializable]

  Public Class SampleClass

  (  ...  )

Code Access Security (CAS) - CAS is the part of the .NET security model that determines whether or not code is allowed to run, and what resources it can use when it is running. For example, it is CAS that will prevent a .NET web applet from formatting your hard disk.  The CAS security policy revolves around two key concepts - code groups and permissions. Each .NET assembly is a member of a particular code group, and each code group is granted the permissions specified in a named permission set. For example, using the default security policy, a control downloaded from a web site belongs to the 'Zone - Internet' code group, which adheres to the permissions defined by the 'Internet' named permission set. (Naturally the 'Internet' named permission set represents a very restrictive range of permissions.)  To view codegroups on our system, use the following command on .NET command interpretor... caspol -lg Note the hierarchy of code groups - the top of the hierarchy is the most general ('All code'), which is then sub-divided into several groups, each of which in turn can be sub-divided. Also note that (somewhat counter-intuitively) a sub-group can be associated with a more permissive permission set than its parent.  If we want to trust a particular website giving it full rights to our system...Use caspol. For example, suppose we trust code from www.mydomain.com and we want it have full access to our system, but we want to keep the default restrictions for all other internet sites. To achieve this, we would add a new code group as a sub-group of the 'Zone - Internet' group, like this: caspol -ag 1.3 -site www.mydomain.com FullTrust  To change the permission, we use the -cg attribute.To turn off caspol, use caspol -s off

Threads - When we want to run one or more instances of a method, we make use of threading. Suppose we have a method like this... Private Sub OnGoingProcess()

 Dim i As Integer = 1

  Do While True
        ListBox1.Items.Add("Repeatitions: " + i)
        i += 1
   Loop
End Sub Dim t As Thread
t = New Thread(AddressOf Me.OnGoingProcess)
t.Start()
 The AddressOf operator creates a delegate object to the BackgroundProcess method. A delegate within VB.NET is a type-safe, object-oriented function pointer. After the thread has been instantiated, you begin the execution of the code by calling the Start() method of the thread. After the thread is started, you have some control over the state of it by using methods of the Thread object. You can pause a thread's execution by calling the Thread.Sleep method. This method takes an integer value that determines how long the thread should sleep. If you wanted to slow down the addition of items to the listbox in the example above, place a call to the sleep method in this code:

Private Sub OnGoingProcess()
    Dim i As Integer = 1

    Do While True
        ListBox1.Items.Add("Repeatitions: " + i)
        i += 1
        Thread.CurrentThread.Sleep(2000)
    Loop
End Sub

 You can also place a thread into the sleep state for an indeterminate amount of time by calling Thread.Sleep (System.Threading.Timeout.Infinite). To interrupt this sleep you can call the Thread.Interrupt method. Similar to Sleep and Interrupt are Suspend and Resume. Suspend allows you to block a thread until another thread calls Thread.Resume. The difference between Sleep and Suspend is that the latter does not immediately place a thread in the wait state. The thread does not suspend until the .NET runtime determines that it is in a safe place to suspend it. Sleep will immediately place a thread in a wait state. Lastly, Thread.Abort stops a thread from executing. In our simple example, we would want to add another button on the form that allows us to stop the process. To do this all we would have to do is call the Thread.Abort method as follows:

Private Sub Button2_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button2.Click
    t.Abort()
End Sub

This is where the power of multithreading can be seen. The UI seems responsive to the user because it is running in one thread and the background process is running in another thread. The cancel button immediately responds to the user's click event and processing stops.   The next example shows a rather simple situation. Multithreading has many complications that we have to work out when we program. One issue that we will run into is passing data to and from the procedure passed to the constructor of the Thread class. That is to say, the procedure we want to kick off on another thread cannot be passed any parameters and we cannot return data from that procedure. This is because the procedure wepass to the thread constructor cannot have any parameters or return value. To get around this, wrap our procedure in a class where the parameters to the method are written as fields of the class.  A simple example of this would be if we had a procedure that calculated the square of a number: 

Function Square(ByVal Value As Double) As Double
    Return Value * Value
End Function To make this procedure available to be used in a new thread we would wrap it in a class:  Public Class SquareClass
    Public Value As Double
    Public Square As Double

    Public Sub CalcSquare()
        Square = Value * Value
    End Sub
End Class

Use this code to start the CalcSquare procedure on a new thread. following code:

Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

    Dim oSquare As New SquareClass()

    t = New Thread(AddressOf oSquare.CalcSquare)

    oSquare.Value = 30

    t.Start()
End Sub

 Notice that after the thread is started, we do not inspect the square value of the class, because it is not guaranteed to have executed once you call the start method of the thread. There are a few ways to retrieve values back from another thread. The easiest way is to raise an event when the thread is complete. We will examine another method in the next section on thread synchronization. The following code adds the event declarations to the SquareClass.

Public Class SquareClass
    Public Value As Double
    Public Square As Double

    Public Event ThreadComplete(ByVal Square As Double)

    Public Sub CalcSquare()
        Square = Value * Value
        RaiseEvent ThreadComplete(Square)
    End Sub
End Class

Catching the events in the calling code has not changed much from VB6, you still declare the variables WithEvents and handle the event in a procedure. The part that has changed is that you declare that a procedure handles the event using the Handles keyword and not through the naming convention of Object_Event as in VB6.  Dim WithEvents oSquare As SquareClass

Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click

    oSquare = New SquareClass()

    t = New Thread(AddressOf oSquare.CalcSquare)

    oSquare.Value = 30
    t.Start()
End Sub

Sub SquareEventHandler(ByVal Square As Double) _
        Handles oSquare.ThreadComplete

    MsgBox("The square is " & Square)

End Sub

 The one thing to note with this method is that the procedure handling the event, in this case SquareEventHandler, will run within the thread that raised the event. It does not run within the thread from which the form is executing.                                                                             (Source: www.devx.com)

Trace and Debug - There are two main classes that deal with tracing - Debug and Trace. They both work in a similar way - the difference is that tracing from the Debug class only works in builds that have the DEBUG symbol defined, whereas tracing from the Trace class only works in builds that have the TRACE symbol defined. Typically this means that you should use System.Diagnostics.Trace.WriteLine for tracing that you want to work in debug and release builds, and System.Diagnostics.Debug.WriteLine for tracing that you want to work only in debug builds.Tracing is actually the process of collecting information about the program's execution.Debugging is the process of finding & fixing errors in our program. Tracing is the ability of an application to generate information about its own execution. The idea is that subsequent analysis of this information may help us understand why a part of the application is not behaving as it should and allow identification of the source of the error.

We shall look at two different ways of implementing tracing in .NET  via the System.Web.TraceContext class via the System.Diagnostics.Trace and System.Diagnostics.Debug classes  Tracing can be thought of as a better (more featureful and automated) alternative to the response.writes we used to put in our old ASP3.0 code to help debug pages! 

 If we set the Tracing attribute of the Page Directive to True, then Tracing is enabled. The output is appended in the web form output. Messeges can be displayed in the Trace output using Trace.Warn & Trace.Write. The only difference between Trace.Warn & Trace.Write is that the former has output in red color. If the trace is false, there is another way to enable tracing. This is done through the application level. We can use the web.config file and set the trace attribute to true. Here we can set <trace enabled=false .../>

Note that the Page Directive Trace attribute has precedence over th application level trace attribute of web.config. While using application level tracing, we can view the trace output in the trace.axd file of the project. For more information on Trace & Debug CLICK HERE                  

 

HOME