Pages

Wednesday, December 17, 2008

Understanding ASP.NET MVC Framework

This post will provide you an architectural overview of the ASP.NET MVC Framework. We will explore the underlying concepts which make up the ASP.NET MVC Framework. This post is not meant to getting you started with creating a MVC Application. It rather gives you the background knowledge needed to work with a MVC application. Creating a MVC application will be the topic of a future post.


Introduction


The ASP.NET MVC Framework helps developers implement the Model-View-Controller pattern. The framework provides a clean separation of concerns in a web application. This gives the developers better control over the applications which are easy to maintain.

The MVC Framework is a shift of thinking from the traditional ASP.NET web applications. In an ASP.NET application, a URL points to a resource or content such as a web page or image which is served by the server. The content must exist before being served else an exception may be thrown. On the other hand, in a MVC application, the URL request is handled by a piece of code. This means that every request is handled by a method of a particular class. So there is basic difference between the two programming models. The prior serves existing contents for a request whereas the later runs a piece of code for a request.

Before we proceed, let’s look at Fig 1. This figure shows the solution when we create an ASP.NET MVC Application using Visual Studio. It has different sub folders including Models, Views and Controllers. A discussion of these sub folders will follow shortly. If you expand the References folder, you will find a reference added to System.Web.Mvc nampspace which is required to work with a MVC application.




Fig 1


Controllers

In a MVC application, a Controller is responsible for handling a request. Each URL request is served by a particular controller. It acts as a bridge between the requests and the application.

In Fig 1, you can see a Controllers folder. All controllers are added under this folder. The controller name must be suffixed with the word ‘Controller’. For example, to create a Product controller, we name it as ProductController. If a user enters the URL /Product, it gets mapped to /ProductController. Even if a controller with the name Product exists, it will not respond to a user request. This is the default behavior for an ASP.NET MVC Application.

A controller is just a C# or VB class. This class is driven from System.Web.Mvc.Controller base class. Listing 1 is an example of a ProductController class:


Listing 1


using System;
using System.Web.Mvc;

namespace MVCDemo.Controllers
{
public class ProductController : Controller
{
public ActionResult Index ()
{
// Add action logic here
throw new NotImplementedException();
}
}
}

A controller consists of Controller Actions. Controller Actions or simply actions are the public methods in a controller. Each request is processed by a controller action in a controller. For example, if a user enters the URL /Product/Index, the Index method in the ProductController class is invoked. Any method which is added as a public method to a controller becomes a controller action. Controller actions have certain properties which include:

• They cannot be overloaded
• All actions must be public
• They cannot be static
• An action returns an ActionResult

The outcome (return type) of a controller action is an Action Result. There are different types of action result, all of which are driven from the base class ActionResult. These action results include:

ViewResult: Returns HTML markup or content to the browser
EmptyResult – Represents no result
RedirectResult – Redirect to a new URL
RedirectToRouteResult – Redirects to a new controller action
JsonResult – Returns JavaScript Object Notation result for AJAX applications
ContentResult – Returns a text result

We are not required to return a particular type of action result directly i.e. we don’t return a ViewResult or JsonResult. Rather we use one of the methods provided by the base class Controller. The different base class methods are:

1. View – Returns a ViewResult action result.
2. Redirect – Returns a RedirectResult action result.
3. RedirectToAction – Returns a RedirectToRouteResult action result.
4. RedirectToRoute – Returns a RedirectToRouteResult action result.
5. Json – Returns a JsonResult action result.
6. Content – Returns a ContentResult action result.

Listing 2 shows controller actions return different types of action results:

Listing 2


using System;
using System.Web.Mvc;

namespace MVCDemo.Controllers
{
public class ProductController : Controller
{
// 1 – return ViewResult()
public ActionResult Index ()
{
return View ();
}

// 2 – redirect to another controller action – RedirectToRouteResult()
public ActionResult RedirectMe ()
{
return RedirectToAction ("Index");
}

// 3 – return content – ContentResult()
public ContentResult ReturnContent ()
{
return Content ("Just a simple string...");
}

public DateTime ReturnDate()
{
return DateTime.Now;
}
}
}

The first controller action (Index) returns a view by calling the base class method. The view returned should correspond to name of the controller action. So a view named Index.aspx is returned to the browser. The location of Index.aspx will come up in the next section.

The base class method RedirectToAction in the second controller action (RedirectMe) redirects the request to the first controller action. The request is redirected to Index.aspx.

Another special type of action result is the ContentResult which returns plain text. Using the base class method Content in the third controller action (ReturnContent), a string is returned to the browser. The source of the page will show you a simple text message with no HTML embedded in it.

If a controller action does not return an action result, it is also treated as ContentResult. The MVC framework calls the ToString () method on the result and wraps it in a ContentResult action result. The fourth action controller will again return current DateTime as a string.



Views

As mentioned, in a MVC application, a request does not map to a page or resource. Rather all requests are handled by actions in a controller. An action can return different types of action results including a View. A view is closest to an asp.net web page since it renders HTML markup and content. Listing 2 has one of the following actions:

public ActionResult Index ()
{
return View ();
}

This action returns a view. The action is invoked by typing in /Product/Index which returns a page Index.aspx from the following location:

\Views\Product\Index.aspx

The location of a view is inferred from the name of the Controller and name of the Controller Action. If you look at Fig 1, you will find a Views folder. All views are under this folder. For the above URL, the Views folder must have a sub folder named after the Controller (Product). The sub folder in turn must have a view page named after the controller action (Index in this case). So a view page Index.aspx is returned to the browser. Figure 2 makes it clear:




Fig 2

We can also explicitly mention the name of the view when calling the return View () statement. For example, the statement ‘return View (“Index”)’ is equal to the statement ‘return View ()’.

A View is an HTML document where scripts are written. Writing a view is a kind of a journey back to the Active Server Pages age. An ASP page does not have the notion of a code behind file. All validation, data handling and business logic code are written on the same page. We make extensive use of Response.Write in traditional ASP application. A script written in a View is somewhat similar to an ASP code.

In a view, script delimiters <% and %> mark the beginning and end of a script. We can then use the Response.Write method to emit some data. For example, the following line will write a string:

<% Response.Write ("This is a view script");%>

In order to save coding time, we can also use the shortcut delimiter <%= %> in place of Response.Write. Listing 3 makes use of both delimiters:

Listing 3


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs"
Inherits="MVCDemo.Views.Home.Index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >

<head id="Index View" runat="server">
<title>Index</title>
</head>

<body>
<div>
<% Response.Write ("MVC framework demo"); %>
<br />
Date-Time: <%=DateTime.Now%>
</div>
</body>
</html>

To facilitate the developers, HTML Helpers are used to add content to a view. HTML Helpers are methods that return a string (such as markup). This way we don’t have to type the HTML markup. These HTML helpers generate standard controls including TextBoxes, hyperlinks, dropdown lists etc. The helper methods are called using the HTML property of the view. The following snippet generates a simple Product entry form using HTML Helpers:

<form method="post" action="/Product/Add">
<label for="ProductName">Product: </label>
<%=Html.TextBox ("ProductName")%>
<br /><br />
<label for="Quantity">Quantity: </label>
<%=Html.TextBox ("Quantity")%>
<br /><br />
<label for="Available"> </label>
<%=Html.CheckBox ("Available", "Available")%>
<br /><br />
<input type="submit" value="Add Product" />
</form>

Notice the use of the delimiters with HTML helper method. Since HTML Helper methods return a string, we need to use Response.Write or the shortcut delimiter <% %> to render the string (control markup) in the browser. For this reason, the above snippet has the Html.TextBox (…) helper method enclosed in a delimiter.

Another interesting property of a view is the ViewData property. ViewData is used by controllers to pass data to a view. The ViewData works like a dictionary holding collections of key-value pairs. Let us look at an example:


public ActionResult ProductDetails ()
{
ViewData ["Info"] = "Available in stock";
return View ();
}

In the above snippet, the action ProductDetails uses ViewData property to pass down the key ‘Info’ with a value ‘Available in stock’ to the view. This key can be used later in the view to retrieve the data with the following code:

<%= ViewData ["Info "] %>

A good use of the ViewData property would be to send database records or XML data to a view. The controller action can access the database and pass the data to the view. This also results in a clean separation of concerns where data access is separate from the view. Similarly an action can read a file and send its contents to the view.



Models

The controllers hold logic to handle incoming request and views represent the UI of a MVC application. Where does the business logic and data access code reside? This is where Models come into play. Models are responsible for hosting the business logic. They also hold data access components. For example, we can have DAL (Data Access Layer) classes, Entities or LINQ to SQL classes as models. In fig 1, you can see a Models folder. All data access classes must be placed under this folder.

As a best practice, fat models and thin controllers are recommended. The controller should only be concerned with handling requests whereas the models should deal with business logic and data access code. Even if a controller is passing data to a view fetched from the model, it should be limited to making calls to the model. This also results in a clean separation of concerns in a MVC application.



URL Routing

So how does a piece of code get executed when a request is made in a MVC application? This is where the URL Routing comes into play. URL Routing is a key feature of a MVC application. It is a mechanism through which a URL is mapped to a controller action. URL Routing is handled in the Web.Config and Global.asax file.

The Global.asax handles the application lifecycle events. One of these events is the Application_Start event which is raised when an application starts. Listing 4 shows the Global.asax:

Listing 4 – Global.asax


using System.Web.Mvc;
using System.Web.Routing;

namespace HelloMVC
{
public class GlobalApplication : System.Web.HttpApplication
{
public static void RegisterRoutes (RouteCollection routes)
{
routes.IgnoreRoute ("{resource}.axd/{*pathInfo}");

routes.MapRoute (
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }
// Parameter defaults
);
}

protected void Application_Start ()
{
RegisterRoutes (RouteTable.Routes);
}
}
}

The Application_Start event calls the RegisterRoutes method. The RegisterRoutes method creates a route table.

The default route table contains of a single route (Default). If you look at above listing, you can see that the Default route maps the first segment of a URL to a controller name, the second segment of a URL to a controller action, and the third segment to a parameter named id. This means that a request such as /Prodct/Add/20 will look for a controller Product with action Add and a parameter to add equal to 20.

The Default route includes defaults for all three parameters. If you don’t supply a controller, then the controller parameter defaults to the value Home. If you don’t supply an action, the action parameter defaults to the value Index. Finally, if you don’t supply an id, the id parameter defaults to an empty string.

Let us see a few examples of URL mapping. Suppose we enter a URL

/Home/Index/2

The parameters for this URL are:

Controller = Home
Action = Index
Id = 2

The code generated for these parameters is

HomeController.Index (3)

Similarly if the URL is

/Product/Delete/19

It is converted to:

Controller = Product
Action = Delete
Id = 19

Now the code generated is

ProductController.Delete (19)

The default route table is fine for a general MVC application. However, we can also create custom routes depending on our routing needs. For example, we are creating an Online Reporting System. This system helps user create and maintain reports. The reports are maintained on a date-by-date basis. The user is allowed to enter a URL like:

/Files/06-19-2008

To handle such request, let us edit Global.asax in listing 5 with our new route defined:

Listing 5


using System.Web.Mvc;
using System.Web.Routing;

namespace MVCDemo
{
public class GlobalApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"OnlineReporting",
"Files/{DateModified}",
new {controller = "Files", action = "Modified"}
);

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }
// Parameter defaults
);

}

protected void Application_Start()
{
RegisterRoutes (RouteTable.Routes);
}
}
}

The order in which routes are added matters. The OnlineReporting route is added before the default blog. If it is placed after the default route, the default route will always get called before the custom route. Hence our request won’t be handled resulting in an exception.

For the OnlineReport route to work, we must have a Files controller and a Modified action controller. When the Modified method is invoked, DateModified is passed in as parameter. So the code generated is

Files.Modified (DateModified)
Since this method accepts datetime as parameter, the MVC framework converts the parameter to a datetime value.



Summary

In this blog entry, we looked at the architecture of an ASP.NET MVC application. Unlike asp.net applications, a request is handled by a Controller. A Controller is class which can have public methods known as Controller Actions. The request invokes the controller action of a controller. The result of a controller action is of type Action Result. There are different types of action results. We can use methods of the base class Controller to return different types of results.

A view is similar to an asp.net page which renders html markup to a browser. In a view, delimiters <% %> mark the start and end of a script. To render markup on a page, HTML Helper methods are available in a view. These helper methods rid us of writing markup code by rendering controls on a page. The ViewData property of a view is used to pass down information from a controller to a view.

Models take care of business logic and data access in a MVC application. The models can consist of DALs, Entities and LINQ to SQL classes. To maintain clean separation of concern, we should favor fat models and thin controllers.

URL Routing is another important feature of a MVC application. It handles and supports user friendly URLs. To handle URLs, a route table is created in the Global.asax file using the Applicatin_Start event handler. This table defines the parameters for a URL which includes the controller, the controller action and any id passed to the controller action. Finally we can also setup custom routes to handle any special routing need.

I hope this post has given you sufficient insight into ASP.NET MVC architecture. In a future post, I will talk about creating and working with a MVC application. So stay tuned…

Thursday, December 11, 2008

LINQ Explained– Part 2

This is the second part of my on going series on LINQ. In the first installment, we had an overview of LINQ. In this post, we will look at some of the underlying concepts which are important to understand to work with LINQ. Though you are not required to master them but an understanding of these concepts gives you the extra level of confidence to work with LINQ. (Note: I will use C# as language of preference in this series).

LINQ and C# Language

LINQ works with C# 3.0 and Visual Basic 9.0. It relies heavily on the features provided by these languages. Although these features may be used separately, they are fundamental to the working of LINQ. Some of these features were delivered with C# 1.x and 2.0 – the predecessor to C# 3.0. The following sections describe these features in more detail.

Generics

Let us look at a simple example of comparing two numbers. The following method accepts two integers as argument, compares them and returns the result:

private int Compare (int x, int y)
{
return x < y ? x : y;
}

This code works fine for comparing two integers. But suppose we wanted to compare two floating values or even two strings. For this purpose, either we change the method signature to accept the respective types or we end up writing entirely new methods for each type. But as developers, we would be inclined towards using a generalized method to perform the same function irrespective of the argument types.

One solution to the above problem is to accept object as arguments. In C#, every type is driven from the base type object so it can be cast to and back from the object type. We can rewrite the above method as following:


private object Compare (object x, object y)
{
// comparison logic goes here
}

The above method now accepts object as argument. This makes the method more generalized but with some shortcomings. First of all, C# is a type-safe language, that is, objects have associated type and only operations defined by the associated types can be performed on an object. A comparison operator such as ‘<’ will not operate on the reference type object. Thus a conversion of object to a value type is required before the comparison is performed. This means to use a type, explicit casting required. For example, to convert to an integer, we write the following code:

int i = (int) x;
int j = (int) y;

Similarly, to check for string, we perform the following casting:

string str1 = (string) x;
string str2 = (string) y;

Second, when a value type is converted to a reference type (boxing), it involves an overhead. A conversion back to the value type from a reference type (unboxing) also involves an overhead. As a result of boxing and unboxing, there is a performance hit for an application. This is further magnified when Collections are used. Collections such as Stack, Queue, ArrayList operate on object type only. When an element is added to a collection, boxing takes places. Similarly, when a value is retrieved from the collection, unboxing is done. This means every time an element is added or retrieved from a collection, a performance overhead is involved.

The above issues can be catered through Generics. A C# 2.0 language feature, Generics introduced the concept of type parameters. Classes and methods can defer the definition of one or more type until runtime. With Generics, there is one implementation for all types. The type definition is performed when the method is invoked or an object is instantiated. Let us redefine our Compare method using Generics:



private T Compare <T> (T x, T y) where T : IComparable <T>
{
return x.CompareTo (y) < 0 ? x : y;
}

A placeholder <T> appended to the method name points to a generic method. The placeholder <T> represents the type parameter to be provided when this method is used. The same placeholder is used for the input and output parameters. Note that since <T> is just a placeholder (and not a type), the CompareTo method cannot operate on it directly. For this reason, <T> implements the IComparable interface. We will look at the ‘where’ constraint shortly. For now we can use the above method for the comparison of different types as following:

int a = 20, b = 19;
int c = Compare <int> (a, b);

string str1 = "Zzzz", str2 = "Aaaa";
string str3 = Compare <string> (str1, str2);

Notice that there is no explicit casting required for the arguments. The method is invoked with the type parameter inplace of the placeholder and that’s it. The CLR is responsible for handling the rest.

The Generic concept also applies to classes and structures. Let us look at a Generic class:




public class UserAuthentication <T>
{
private T myPassword;
private string myUserID;

public T Password
{
get { return myPassword; }
set { myPassword = value; }
}

public string UserID
{
get { return myUserID; }
set { myUserID = value; }
}
}

The above class creates a token for user authentication. Notice the placeholder <T> defined next to the class name. The password field is of the same type parameter. Similarly the Password property has a returns type of <T>. We can instantiated the above class with following code:


UserAuthentication <string> userAuth;

userAuth = new UserAuthentication <string> ();
userAuth.Password = "Secret";
userAuth.UserID = "User1";

UserAuthentication <int> userAuth;

userAuth = new UserAuthentication <int> ();
userAuth.Password = 123456;
userAuth.UserID = "User2";

.NET framework supports different generic collections under the System.Collections.Generic namespace. These generic collections include:

Stack <T> - a generic collection representing a Last-In-First-Out collection
Queue <T> - a generic collection representing a First-In-First-Out collection
List <T> - a generic collection of strongly type object list
Dictionary <K, V> - a generic collection of key-pair values

Let us see a generic List in action which accepts a strongly-typed parameter. We first define the strong-type Product followed by the generic list:



public class Product
{
string productName;

public Product (string pName)
{
productName = pName;
}

public string ProductDetails
{
get
{
return "Product-Name: " + productName;
}
}
}

public class ProductList <T> : IEnumerable <T> where T : Product
{
List <T> productList = new List <T> ();

public void AddProduct (T product)
{
productList.Add (product);
}

public T GetProduct (int index)
{
return productList [index];
}

IEnumerator <T> IEnumerable <T>.GetEnumerator ()
{
return productList.GetEnumerator ();
}

IEnumerator IEnumerable.GetEnumerator()
{
return productList.GetEnumerator ();
}
}

We can now use the ProductList class to add and list products (a discussion of IEnumerable will follow shortly):


ProductList <Product> productList = new ProductList <Product> ();

productList.AddProduct (new Product ("Rice"));
productList.AddProduct (new Product ("Milk"));
productList.AddProduct (new Product ("Sugar"));

… = ((Product) productList.GetProduct (1)).ProductDetails;

Before I sum up the generics discussion, one last thing worth mentioning is constraints. If you have noticed in the ProductList class (and the Compare method), there is a use of ‘where’ constraint. A constraint is a condition applied on the type parameter. We can use constraints to treat only specific types. For this reason the constraint ‘where T : Product’ is added to the class definition. This way we create a generic list which only deals with Product objects. We can have the following different constraints attached to the generic type:

where T : class – type parameter is a reference type
where T : struct – type parameter is a value type
where T : new () – type parameter with a default constructor
where T : interface – type parameter implements an interface


Delegates

A delegate is an object which holds a reference to a method. When the delegate is called, the underlying method is invoked. This way a delegate behaves exactly like the referenced method. The method can either be static or an instance method. A delegate defines the method signature and any method with matching signature can be reference by the delegate. This makes it possible to change the reference to a different method programmatically and update the code in the methods without modifying the delegate. This simple concept of abstraction adds lots of power to the .NET Framework (A detailed discussion of delegates is beyond the scope of this post. A detailed post or two would cover delegates, events, asynchronous callback and threading in the future).

Working with delegates is a pretty simple in C#. Always keep in mind the method signature when defining a delegate. Let us look at the syntax of defining a delegate:

delegate result-type Name (parameters);

The delegate keyword is used as prefix to define the delegate. The result-type reflects the return type from the referenced method. The Name is the identifier of the delegate and the optional comma separated parameters are the input argument to the referenced method. The result-type and parameters define the signature of the delegate. Using the above syntax, we can create a delegate as following:

public delegate void Calculate (int value, int amount);

Any method with matching signature can be referenced by the above delegate. Let us define a method with the matching signature:



public class Accounts
{
public void DebitAccount (int x, int y)
{
int sum;
sum = ((x * 10) / y) * 2;
// use sum…
}
}

We can now instantiate and invoke the delegate by referencing the DebitAccount method as following:

Accounts objAccount = new Accounts ();
Calculate calc = new Calculate (objAccount.DebitAccount); // reference method
calc (2, 3); // call delegate

When we call the delegate, the DebitAccount method is invoked.

Multicasting is one of the features provided by delegates. A multicast delegate can reference more than one method at a time. When the delegate is called, all the referenced methods are invoked. The methods are invoked in the order in which they are referenced by the delegate. Let us modify the Accounts class by adding the following method to it:



public void CreditAccount (int x, int y)
{
int average;
average = ((x / 2) + 10) - y;
// use average…
}

The calc delegate can now reference the above method using the compound assignment operator (+=):

calc += objAccount.CreditAccount;

Now if the call the delegate using calc (2, 3), both methods get invoked. Once you have used a delegate, the reference must be released. References can be removed using the compound subtraction statement or null value assignment as following:
calc -= objAccount.CreditAccount; // remove reference to CreditAccount
calc = null; // remove all references

Delegates are also used for Asynchronous Callbacks. When asp.net receives a request for a page, it assigns a thread from the thread-pool to the requested page. In a synchronous call, the page holds on to the thread for the duration of the request, blocking calls to the thread for new requests. This is acceptable for a short lived request but if the request is time-bound such as calling multiple web services or an I/O bound job, the delay is annoying.

Delegates help perform asynchronous tasks using Method Callback. With this technique, the delegate invokes the time-consuming method in a separate thread and the control returns immediately. The time-bound task executes in the background while we can continue with our processing. When the background job is finished, control is transferred to a callback method which can handle the result and update any control. Let me demonstrate this concept with an example. We first write the time-consuming process as following:



// the time consuming process
public bool LongProcess (int wait)
{
// your lengthy task goes here
System.Threading.Thread.Sleep (wait); // just for demonstration
return true; // return the result
}

Next we declare a delegate and use it to invoke the above method.


// define the delegate
public delegate bool LengthyProcessDelegate (int wait);

User clicks on a button to start the process:


// Use the delegate to start the lengthy process
protected void StartProcessing_Click (object sender, EventArgs e)
{
LengthyProcessDelegate lDelegate = new LengthyProcessDelegate (LongProcess);
lDelegate.BeginInvoke (5000, new AsyncCallback (LongProcessCallback), lDelegate);
for (int i = 0; i <= 50; i++)
{
// do something
}
}

The above code first creates a new instance of the delegate which holds rerference to the time-consuming method. Next it calls the BeginInvoke method using the delegate. You must be wondering what this method is? Remember, when we declare a delegate, the compiler generates code similar to the following:


class LengthyProcessDelegate : System.MulticastDelegate
{

// synchronous execution
public bool Invoke (int wait);

// asynchronous execution methods
public IAsyncResult BeginInvoke (int wait,
AsyncCallback callback,
object asyncState);

public bool EndInvoke (IAsyncResult result);
}

The Invoke method is used for sychronous calls. The other two methods, BeginInvoke and EndInvoke handle the asynchronous activity.

BeginInvoke method returns an instance of interface IAsyncResult. It accepts the same arguments as defined by the delegate plus two additional optional parameters. The first parameter is an instance of AsyncCallback (another delegate) which references the callback method. The second parameter is of type object which can be used to pass any information.

The EndInvoke method has the same return type as defined by the delegate. It accepts an instance of IAsyncResult. As mentioned above, BeginInvoke returns an instance of IAsyncResult. This instance is passed down to the callback method which is used by the EndInvoke method as parameter. It in turn returns the result of the time-consuming method which can be used for further processing. Let us look at the callback method in action:



// Callback method
public void LongProcessCallback (IAsyncResult result)
{
LengthyProcessDelegate lDelegate= (LengthyProcessDelegate) result.AsyncState;
bool returnValue = lDelegate.EndInvoke (result);
// use returnvalue
}

As mentioned above, when BeginInvoke is called, the delegate invokes the callback method in a separate thread and the control returns to the program immediately. If you have noticed above, I have got a dummy loop after the call to BeginInvoke method. This is just to show you that the processing will continue and not wait for the time consuming process to complete.

delegates also provide a rich programming model to handle Events. An event lets an object notify the program when its state changes. Events allow objects to provide noification to be responded. This simple concept is very important for inter-process communication where the change of state of one object signals other objects to respond. A good example of events is a Graphical User Interface. The program transfers the control to an event handler when an event such as Button-Click is triggered by the user action. Another example would be an Accounts object raising an event when a transaction is made.

In C# events and delegates go hand-in-hand. Any object which triggers an event isn’t aware when the event is raised. This is left to a delegate which act as a bridge between the object and the event. Let us see this concept with a simple example. We begin with defining a delegate:

// define the delegate
public delegate void AccountDelegate (); // no input, output parameters

Next we define an Accounts class. This class has a Transaction property which fires an event when its value changes. The event is defined using the AccountDelegate. Since the delegate’s signature does not have any input or output parameter, the event handler for the event will have a similar signature. The event handling method OnTransactionOccur is defined as virtual which can be overridden by derived classes.



public class Accounts
{
private int amount;
// define the event
public event AccountDelegate transactionComplete;

public int Transaction
{
get { return amount; }

set
{
if (value <= 100)
amount--;
else
amount++;

OnTransactionOccur (); // raise the event
}
}

protected virtual void OnTransactionOccur ()
{
if (transactionComplete != null)
transactionComplete ();
}
}

We can now raise the event with the following code:


public void StartProcessing_Click (object sender, EventArgs e)
{
Accounts account = new Accounts ();
// register the event
account.transactionComplete += new AccountDelegate (AccountEventHandler);

account.Transaction = 100; // raise the event
}

First we instantiate an object of Accounts class. Next we register the event using the delegate with the event handler AccountEventHandler. We then set the Transaction property to raise the event. Remember the base class method OnTransactionOccur is actually responsible for raising the event. As soon as the event is raised, the control is transferred to the following event handler.


public static void AccountEventHandler ()
{
// event handling code goes here
}

Enumerators

Enumeration, a powerful .NET concept, allows us to iterator through a collection of objects. In .NET, enumerators are based on the Iterator Pattern. Using this pattern, we can access elements of an aggregate (combination of many elements) object without revealing the inner working. The terms Enumerators and Iterators are used interchangably but .NET uses the term Enumerator.

A class must implement the IEnumerable interface to provide iteration. This interface exposes the following single method:



public interface IEnumerable
{
IEnumerator GetEnumerator ();
}

The GetEnumerator method returns an object of IEnumerator interface. This object does the actual iteration on our collections. According to MSDN, Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection. Enumerator interface exposes the following methods:


public interface IEnumerator
{
bool MoveNext();
object Current{ get; }
void Reset();
}

When we implement our own enumerators using the IEnumerator interface, the enumerator is positioned before the first element initially. To read the first (and subsequent) element, we use the MoveNext method. MoveNext method returns true until the end of the collection is reached. When MoveNext reaches the end of the collection, it returns false. To get the active element, we use the Current method. The Reset method positions the enumerator before the first element.

Let me demonstrate the above concept by a simple example. I begin by defining (beaten to death :-) Product class as following:



public class Product
{
private string productID;
private string productName;

public Product (string id, string name)
{
productID = id;
productName = name;
}

public override string ToString()
{
return String.Format ("Product details are ID: {0}, Name: {1}", productID,
productName);
}
}

Next we define our Custom Collection class which implements IEnumerable interface:


public class ProductCollection : IEnumerable
{
private ArrayList productList;

public ProductCollection ()
{
productList = new ArrayList ();

productList.Add (new Product ("P1", "Tea"));
productList.Add (new Product ("P2", "Beverage"));
productList.Add (new Product ("P3", "Milk"));
}

public IEnumerator GetEnumerator ()
{
return ((IEnumerable) productList).GetEnumerator ();
}
}

I have used an arraylist to define a product collection. Since the arraylist already implements the IEnumerable interface, we can get hold of the its enumerator object by calling its respective GetEnumerator method. The enumerator object can be used with foreach loop to provide enumeration:


public void StartProcessing_Click (object sender, EventArgs e)
{
ProductCollection collection = new ProductCollection ();

foreach (Product p in collection)
// ListBox1.Items. Add (p.ToString ()); - ading to a listbox
}

The foreach statements simplifies the enumeration code for us. Under the hood, when we use the foreach loop, the compiler generates an initial call to GetEnumerator. It then uses MoveNext for each iteration to get the current item. Since the enumerator is positioned before the first element, the compiler doesn’t have to call the Reset method.

We can also create our own Enumerator class by implementing the IEnumerator interface. Let us modify our ProductCollection class with a nested class as following:



public class ProductEnumerator : IEnumerator
{
private ProductCollection productCollection;
private int index;

public ProductEnumerator (ProductCollection collection)
{
productCollection = collection;
index = -1;
}

public void Reset()
{
index = -1;
}

public object Current
{
get
{ return productCollection.productList[index]; }
}

public bool MoveNext()
{
index++;
if (index >= productCollection.productList.Count)
return false;
else
return true;
}
}

Here is the tricky part. We used the GetEnumerator method of the ArrayList to get an enumerator object. We will modify that code to return an instance of our custom enumerator as following:


public IEnumerator GetEnumerator()
{
return (IEnumerator) new ProductEnumerator (this);
}

One last thing worth mentioning are generic enumerators. These enumerators are used for a generic collection. The two interfaces are IEnumerable<T> and IEnumerator<T> found in System.Collections.Generic namespace. Both these interfaces inherit from their counterpart IEnumerable and IEnumerator. This means that generic enumerable objects are available both generically and non-generically. Let us first look at the IEnumerable<T> interface:


public interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

IEnumerable<T> inherits from IEnumerable. This means any collection implementing IEnumerable<T> interface must define a generic and non-generic version of GetEnumerator method. So a generic collection class will have the following two implementations of GetEnumerator method:


public IEnumerator<T> GetEnumerator()
{
return new Enumerator<T>(this);
}

IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator<T>(this);
}

The same concept applies to IEnumerator<T>. This interface is defined as following:


public interface IEnumerator<T> : IDisposable, IEnumerator
{
T Current { get; }
}

IEnumerator<T> interface implements IDisposable and IEnumerator interface. It has only one property. So any class implementing IEnumerator<T> inherits the rest of the members from IEnumerator and Idisposable interfaces.

Summary

In this post, we looked at some of the underlying concepts which help us better understand how LINQ works. Generics have introduced the concept of type parameter where the type definition is delayed till an object is instantiated. A place holder <T> defines a generic type. Generics apply to methods, classes and structures. We can apply constraints to our generic type to accept fixed type parameters. The .NET Framework ships with built in generic types such as Queue <T>, Stack <T> to reduce the development overhead.

Another feature important to understand LINQ is delgates. Delegates are objects which hold reference to methods. A call to the delegate invokes the reference method. Delegate can also hold reference to multiple methods. This property is known as multicating. Delegates are also used for asynchronous callbacks. Using a delegate, a callback method is attached to a long running process. After the process has finished, the delegate transfers control to the callback method which can retrieve the result and process it. Delegates also move hand-in-hand with events which notify us of a change. We can then write our event handlers to responsd to these changes.

We also looked at enumerators. Enumerators are used to iterate through the elements of an aggregate object. All enumerators implement IEnumerable and IEnumerator interfaces to provide iteration. The foreach comes in handy to iterate through a collection. Generic collections can also take advantage of enumerators by implementing IEnumerable <T> and IENumerator <T> interfaces.

When I sat down to write this post, I thought of explaining all the underlying concept in this post. But each topic is worth a separate post. For this reason, I will sum up the rest of the concept in the next post. Please do provide your feedback on this series and stay tuned for more…