Tuesday, December 7, 2010

Choosing between Abstract class and Interface

The choice of whether to design your functionality as an interface or an abstract class (a MustInherit class in Visual Basic) can sometimes be a difficult one. An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes. For details, see Abstract Classes.

An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.

An advantage of Abstract class over Interface
If you want to have additional functionalities for the interface, you must implement the new ones in all of the classes that implement the changed interface. The code will not work until you make the change. But if you want to have additional functions to the Abstract class, you can have default implementation. Your code still might work without many changes.

An advantage of Interface over Abstract class
A class can inherit multiple interfaces but can inherit only one class.

When to Use Abstract and When to Use Interface:

Let me explain it with reference to the scenario.
Let us take a classification called Human. As it is a very general classification, I can put all the Human related common data in Abstract class.These common data could be First Name, Last Name, Gender, Education, Occupation, Residence, etc. with some functions as virtual (or overridable), e.g., an occupation which differs from human to human.

Aim of Interface: We want the implementing object to acquire this ability.
Aim of Abstraction: We want the derived object to belong to some group. Abstraction gives the Identity to the derived object.

The sentence "Object A is a Human" is more meaningful than the sentence "Object A is an object which has the ability to walk." (Human can walk, an animal, a bird, a machine - consider it is a robot ... that can also walk.)

Why I chose interfaces IEat, IWalk, IDance and ISing

I may want Object A to walk in the morning, to eat in the afternoon or to dance in the evening, or I may not be aware at a particular time what these objects should be doing. The capability of Object A at a particular time is unknown to me. Also every derived object may need not posses the quality of walking, or dancing, or singing. An infant cannot walk, as you know everybody cannot dance and sing. So I created these interfaces so that I can define the combination of these capabilities for different objects explicitly.


Refer to the image below for a more clearer view.



Take an example of .NET interfaces IDisposable or IComparable. We implement these interfaces only if necessary. We implement IDisposable mostly when we want to handle COM components and IComparable to compare and sort the objects in an Array.

If you want your class to have an Identity of Form, you must inherit Form class and you can add the ability to dispose, by implementing IDisposable, only if you want to dispose it manually.

Reusability
Let us consider the same abstract Human class which has the virtual function Eat instead of an Interface IEat.
Now I want to create a class called Bird. As a Bird can also eat, I want to reuse the function which is already there in Human class. Suppose, just because abstract Human class has the function to eat, I cannot derive a Bird class from that. I will tend to change the Bird's identity by doing so, or I may load unnecessary properties to the Bird that could be an education, or employment, or may be the last name. Even worse I may need to change the abstract Human class so as to include the common behaviors of Bird category. This is totally senseless and messes up the class and objects. Instead, I can have another Abstract class for Birds and choose to have an interface called IEat, which could be implemented by an object of Human and also an object of Bird.







Polymorphic Behavior:
Both interfaces and abstract classes are useful for component interaction. If a method requires an interface as an argument, then any object that implements that interface can be used in the argument. For example:
 
' Visual Basic
Public Sub Spin (ByVal widget As IWidget)
End Sub
// C#
public void Spin (IWidget widget)
{}
This method could accept any object that implemented IWidget as the widget argument, even though the implementations of IWidget might be quite different. Abstract classes also allow for this kind of polymorphism, but with a few caveats:
  • Classes may inherit from only one base class, so if you want to use abstract classes to provide polymorphism to a group of classes, they must all inherit from that class.
  • Abstract classes may also provide members that have already been implemented. Therefore, you can ensure a certain amount of identical functionality with an abstract class, but cannot with an interface.

Conclusion :

  • Abstract class gives an Identity to the derived object.
  • Interface extends the ability of an object.
  • Interfaces give polymorphic behavior.
  • Abstract class also gives polymorphic behavior. But it is more meaningful to say that Abstract class simplifies versioning, as the base class is flexible and inheriting class can create many versions of it by additional functions and also by implementing Interfaces.
  • Interfaces and Abstract classes both promote reusability.

Here are some recommendations to help you to decide whether to use an interface or an abstract class to provide polymorphism for your components.
  • If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, you must create a whole new interface.
  • If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes.
  • If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.
  • If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.

References :
CodeProject
MSDN

Monday, August 23, 2010

URL Routing on IIS7 and ASP.NET 3.5 with SP1

Purpose : To allow users browse your site using extensionless and user-friendly urls.
Step1: Add a Reference to System.Web.Routing to Your Project
Step2: 
Add UrlRoutingModule to 'httpModules' under <system.web> and to 'modules' under  <system.webServer>;
Add UrlRoutingHandler to 'handlers' section under <system.webServer>

<configuration>
   ...

   <system.web>
      ...
      <httpModules>
         ...
         <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </httpModules>

   </system.web>

   <system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      <modules>
         ...
         <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </modules>


      <handlers>
         ...
         <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </handlers>
      ...
   </system.webServer>

</configuration>

Step 3: Define the Routes in Global.asax

Define one to many routes in Application_Start event of global.asax.

Here in this example defined a route to 
SchoolType/SchoolName - used to view school detail page. (where actually you have to go to this page by virtual path 'ViewSchool.aspx?schoolid = 14')


<%@ Import Namespace="System.Web.Routing" %>
<script runat="server">
void Application_Start(object sender, EventArgs e) 
{
     RegisterRoutes(RouteTable.Routes);
}

void RegisterRoutes(RouteCollection routes)
{
    routes.Add("ViewSchool", new Route("{SchoolType}/{*SchoolName}", new   SchoolRouteHandler()));
}
</script>

Step 4: Create the Route Handler Classes
 A route handler class is a class that is passed information about the incoming request and must return an HTTP Handler to process the request. It must implement the IRouteHandler  interface and, as a consequence, must provide at least one method - GetHttpHandler - which is responsible for returning the HTTP Handler (or ASP.NET page) that will process the request.
Typically, a route handler performs the following steps:
  1. Parse the URL as needed
  2. Load any information from the URL that needs to be passed to the ASP.NET page or HTTP Handler that will handle this request. One way to convey such information is to place it in the HttpContext.Items collection, which serves as a repository for storing data that persists the length of the request.
  3. Return an instance of the ASP.NET page or HTTP Handler that does the processing

public class SchoolRouteHandler : IRouteHandler
{
     public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string schoolType = requestContext.RouteData.Values["SchoolType"] as string;
        string schoolName = requestContext.RouteData.Values["SchoolName"] as string;
      
        if (string.IsNullOrEmpty(schoolName) || string.IsNullOrEmpty(schoolType))
            return BuildManager.CreateInstanceFromVirtualPath("~/schoolnotfound.aspx", typeof(Page)) as   
            Page;
        else
        {
            //Code here to get school id from database 
           //store values, whichever you want to pass them to .aspx page

            HttpContext.Current.Items["SchoolType"] = schoolType;
            HttpContext.Current.Items["SchoolID"] = schoolid;

            return BuildManager.CreateInstanceFromVirtualPath("~/viewschool.aspx", typeof(Page)) as Page;
        }
            return BuildManager.CreateInstanceFromVirtualPath("~/schoolnotfound.aspx", typeof(Page)) as         Page;
    }
}

Step 5: Create the ASP.NET Pages That Process the Requests

protected void Page_Load(object sender, EventArgs e)
   //Retrieve values back from httpcontext
   Int64 schoolid = Convert.ToInt64(
HttpContext.Current.Items["schoolid"]);

If you do till here it will work fine on your local system using development server.  But, when you host the website on a shared server you get HTTP 404 page. This means IIS receives the request and it serves the page configured for HTTP 404. Generally this is a 404.html file that resides in IIS directory. IIS does not send the request to ASP.NET handler and thus you cannot intercept 404 requests. So, if you can forward all HTTP 404 to ASP.NET, you can serve such extensionless URL. In order to forward HTTP 404 to ASP.NET ISAPI, all you need to do is configure IIS to redirect to some .aspx extension when a missing extensionless url is hit.

Step6:
Add below section to your web.config , under <system.webserver>
<httpErrors errorMode="Custom">
     <remove statusCode="404" subStatusCode="-1" />
     <error statusCode="404" prefixLanguageFilePath="" path="/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

When you will request an URL like "www.findaschool.in/preschools/drskids" it will redirect to "www.findaschool.in/404.aspx?404;http://www.findaschool.in/preschools/drskids". From Global.asax BeginRequest event, capture this URL and see whether it's an extensionless URL request. If it is, do your URL rewriting stuff for such extensionless URL.


protected void Application_BeginRequest(object sender, EventArgs e)
{
      string url = HttpContext.Current.Request.Url.AbsolutePath;
   
      // HTTP 404 redirection for extensionless URL or some missing file
      if (url.Contains("404.aspx"))
      {
          // On 404 redirection, query string contains the original URL in this format:
          // 404;http://www.findaschool.in/preschools/drskids    
          string[] urlInfo404 = Request.Url.Query.ToString().Split(';');
          if (urlInfo404.Length > 1)
          {
              string originalUrl = urlInfo404[1];
System.Uri rwUri = new Uri(originalUrl);
              HttpContext.Current.RewritePath(rwUri.PathAndQuery); 
}
}
}

More detailed information at below links:
  •  http://www.4guysfromrolla.com/articles/051309-1.aspx
  •  http://www.codeproject.com/KB/aspnet/extensionless.aspx
  •  http://blogs.msdn.com/b/tmarq/archive/2010/04/01/asp-net-4-0-enables-routing-of-extensionless-urls-without-impacting-static-requests.aspx

Friday, August 20, 2010

Uploading a large file using FileUpload Control in ASP.NET

By default FileUpload control in asp.net uploads upto 4MB size of files and it doesn't allow 'exe' files.

To increase the file size limit that a fileupload control can upload, just add the following line to web.config

< system.web >
< httpruntime executiontimeout="500" maxrequestlength="4096" >
< /system.web >

Here 'executionTimeout' in milliseconds and 'maxRequestLength' in kb. So, increase the maxRequestLength to upload large files.