Labels:

Here is a very useful C# code snippet for generating random strong passwords. The password is generated using upper case and lower case alphabets, numerals and special characters.



//create constant strings for each type of characters
static string alphaCaps = "QWERTYUIOPASDFGHJKLZXCVBNM";
static string alphaLow = "qwertyuiopasdfghjklzxcvbnm";
static string numerics = "1234567890";
static string special = "@#$";
//create another string which is a concatenation of all above
string allChars = alphaCaps + alphaLow + numerics + special;
Random r = new Random();
 
public string GenerateStrongPassword(int length)
{
    String generatedPassword = "";
 
    if (length < 4)
        throw new Exception("Number of characters should be greater than 4.");
 
    // Generate four repeating random numbers are postions of
    // lower, upper, numeric and special characters
    // By filling these positions with corresponding characters,
    // we can ensure the password has atleast one
    // character of those types
    int pLower, pUpper, pNumber, pSpecial;
    string posArray = "0123456789";
    if (length < posArray.Length)
        posArray = posArray.Substring(0, length);
    pLower = getRandomPosition(ref posArray);
    pUpper = getRandomPosition(ref posArray);
    pNumber = getRandomPosition(ref posArray);
    pSpecial = getRandomPosition(ref posArray);
 
 
    for (int i = 0; i < length; i++)
    {
        if (i == pLower)
            generatedPassword += getRandomChar(alphaCaps);
        else if (i == pUpper)
            generatedPassword += getRandomChar(alphaLow);
        else if (i == pNumber)
            generatedPassword += getRandomChar(numerics);
        else if (i == pSpecial)
            generatedPassword += getRandomChar(special);
        else
            generatedPassword += getRandomChar(allChars);
    }
    return generatedPassword;
}
 
private string getRandomChar(string fullString)
{
    return fullString.ToCharArray()[(int)Math.Floor(r.NextDouble() * fullString.Length)].ToString();
}
 
private int getRandomPosition(ref string posArray)
{
    int pos;
    string randomChar = posArray.ToCharArray()[(int)Math.Floor(r.NextDouble()
                                   * posArray.Length)].ToString();
    pos = int.Parse(randomChar);
    posArray = posArray.Replace(randomChar, "");
    return pos;
}

Labels:

In this article you can understand how to create thumbnails from images at time of Upload using ASP.NET.I create a small utility class that can convert and image into thumbnails.

Imports
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Drawing2D


Public Class Image_Process
Public Function CreateThumbnail(ByVal lcFilename As String, ByVal targetSize As Integer) As Bitmap
Try
Dim loBMP As Bitmap = New Bitmap(lcFilename)
Dim loFormat As ImageFormat = loBMP.RawFormat
Dim newSize As Size = CalculateDimensions(loBMP.Size, targetSize)
Dim bmpOut As Bitmap = Nothing
bmpOut = New Bitmap(newSize.Width, newSize.Height)
Dim canvas As Graphics = Graphics.FromImage(bmpOut)
canvas.SmoothingMode = SmoothingMode.AntiAlias
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality
canvas.DrawImage(loBMP, New Rectangle(New Point(0, 0), newSize))
Return bmpOut
Catch ex As Exception
Return Nothing
End Try
End Function

Private Function CalculateDimensions(ByVal oldSize As Size, ByVal targetSize As Integer) As Size
Dim newSize As Size = New Size()
If oldSize.Height > oldSize.Width Then
newSize.Width = CInt(oldSize.Width * (CType(targetSize, Single) / CType(oldSize.Height, Single)))
newSize.Height = targetSize
Else
newSize.Width = targetSize
newSize.Height = CInt(oldSize.Height * (CType(targetSize, Single) / CType(oldSize.Width, Single)))
End If
Return newSize
End Function Microsoft.VisualBasic


End Class

The class define above can be use to covert an image into a thumbnail to be display on the list of images.
There is a method CreateThumbnail which can take two parameters and send the output in the form of Bitmap that you can save on your disk.

Below i create a sample program in which i used the above code.

Try
Dim strPath As String = Server.MapPath(Request.ApplicationPath) & "/Images/Original"
Dim filename As String = Guid.NewGuid().ToString().Substring(0, 10) & "" & video_upload.PostedFile.FileName.Remove(0, video_upload.PostedFile.FileName.LastIndexOf("."))' Dim filename As String = video_upload.PostedFile.FileName.Remove(0, video_upload.PostedFile.FileName.LastIndexOf("\") + 1)If Not IsImageFile(filename) Then
ShowMessage("This format is not supported")
Exit Sub
End If
If File.Exists(strPath & "/" & filename) Then
ShowMessage("File already exist, please rename it first")
Exit Sub
End Ifvideo_upload.PostedFile.SaveAs(strPath & "/Photos/" & filename)
video_upload.PostedFile.SaveAs(strPath & "/SnapShots/" & filename)
Dim orignalfilename As String = strPath & "/Photos/" & filename
Dim thumbfilename As String = strPath & "/SnapShots/" & filename

Here i use the function create thumbnail, and pass filename originalfilename that
convert originalfilename into 125px resolution

Dim mp As Bitmap = _img_process.CreateThumbnail(orignalfilename, 125)
If mp Is Nothing Then
ShowMessage("No image generated")
Exit Sub
End If
mp.Save(thumbfilename)

This code will provide you a clear understanding how you can manipulate images at time of upload using ASP.NET

Labels:

Uploading videos, grabbing its thumbnail and converting video to the format that is runnable on the web is now a days a popular source of increasing web site traffic online. One of the main example is www.youtube.com which provides online videos sharing features.

I published my article about Media Handling on the web in real time using FFMPEG and this article helps a lot of web developers and i get a lot of emails from developers. Now in this article i will share knowledge about a component which will really help ASP.NET developers to handle videos on the web on real time. It's Media Handler Pro component introduced recently byhttp://www.mediasoftpro.com . Media Handler Pro is a very fast and powerful encoding ASP.NET encoding component which can encode video from one format to another on the fly using ASP.NET, It is designed especially for Converting videos from any format to FLV format and grab its thumbnail in real time.

I used this component and its awesome.

Main Features included in Component:

  • Convert Videos from any format to FLV Format.
  • Set Meta - Information for FLV Video that flash player need for past play back.
  • Grab Thumbnail Image from FLV Video.
  • Extract Audio from Videos - Suitable for playing audio files , ringtones etc.
  • Convert Videos from any format to MPEG Format.

Examples :

Converting Video to FLV Format (VB.NET):

'// Create object of class Media_Handler.
Dim _mediahandler As New Media_handler()
'// Set Paths for input , output videos.
'// Set Root Path for input , output videos
Dim RootPath As String = Server.MapPath(Request.ApplicationPath)
'// Set Input Video Path.
Dim InputPath As String = RootPath & "/Default"
'// Set Output Video Path.
Dim OutputPath As String = RootPath & "/FLV"
'// Get filename and make it random in order to avoid duplication.
Dim filename As String = Guid.NewGuid().ToString().Substring(0, 10) & "" & video_upload.PostedFile.FileName.Remove(0, video_upload.PostedFile.FileName.LastIndexOf("."))
'// Upload video to input path.
video_upload.PostedFile.SaveAs(InputPath & "/" & filename)
'// After uploading convert uploaded video to flv.
Dim outfile As String = _mediahandler.Convert_Media(filename, RootPath, InputPath, OutputPath, 320, 240, 360, 25, 32, 22050)
'// Where outfile is the name of generated flv file name.


For more examples and sample codes please visit : http://www.mediasoftpro.com/sample-codes.html.


This component use FFMPEG and FLVTOOL in background for Video encoding and decoding. You must put FFMPEG and FLVTOOL in root of your web application in order to work this component properly. You can download FFMPEG and FLVTOOL from their official web sites or from http://www.mediasoftpro.com .

Showing FLV Video on the Web

After successfully encoding of your Video into flv format, you can use any flash player to display this media on your web application like in www.youtube.com.

Labels:

In this example i am going to describe how to send email with attachment in ASP.NET using fileUpload Control. I am saving the uploaded file into memory stream rather then saving it on server.And for this example i m using Gmail SMTP server to send mail, this code also works fine with any SMTP Server. For sending Email in ASP.NET , first of allwe need to add Syatem.Net.Mail namespace in code behind of aspx page.

C# Code Behind

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Net.Mail;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void btnSend_Click(object sender, EventArgs e)
{
MailMessage mail = new MailMessage();
mail.To.Add(txtTo.Text);
//mail.To.Add("amit_jain_online@yahoo.com");
mail.From = new MailAddress(txtFrom.Text);
mail.Subject = txtSubject.Text;
mail.Body = txtMessage.Text;
mail.IsBodyHtml = true;

//Attach file using FileUpload Control and put the file in memory stream
if (FileUpload1.HasFile)
{
mail.Attachments.Add(new Attachment(FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
}
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com"; //Or Your SMTP Server Address
smtp.Credentials = new System.Net.NetworkCredential
("YourGmailID@gmail.com", "YourGmailPassword");
//Or your Smtp Email ID and Password
smtp.EnableSsl = true;
smtp.Send(mail);

}
}

VB.NET Code Behind

Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Net.Mail

Public Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

End Sub
Protected Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim mail As New MailMessage()
mail.[To].Add(txtTo.Text)
'mail.To.Add("amit_jain_online@yahoo.com");
mail.From = New MailAddress(txtFrom.Text)
mail.Subject = txtSubject.Text
mail.Body = txtMessage.Text
mail.IsBodyHtml = True

'Attach file using FileUpload Control and put the file in memory stream
If FileUpload1.HasFile Then
mail.Attachments.Add(New Attachment(FileUpload1.PostedFile.InputStream, FileUpload1.FileName))
End If
Dim smtp As New SmtpClient()
smtp.Host = "smtp.gmail.com"
'Or Your SMTP Server Address
smtp.Credentials = New System.Net.NetworkCredential("YourGmailID@gmail.com", "YourGmailPassword")
'Or your Smtp Email ID and Password
smtp.EnableSsl = True

smtp.Send(mail)
End Sub
End Class

Labels:

Once you have published a site in ASP.NET, you'd like to know who are your visitors. One way is to check your event log on the host server. Another option is to write your own code. You'd basically like to log the IP address, and DNS name for the visitor, and it would be nice to know which page they are visiting.

To log the ip address using ASP.NET, you can call:

Request.ServerVariables["HTTP_X_FORWARDED_FOR"]

Another usefull variable is

Request.ServerVariables["REMOTE_ADDR"]

A combination of the two can be done as follows:

private string IpAddress()

{

string strIpAddress;

strIpAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

if (strIpAddress == null)

{

strIpAddress = Request.ServerVariables["REMOTE_ADDR"];

}

return strIpAddress;

}

Next, you'd want to log the DNS name. To do so, you can call:

Dns.GetHostByAddress(string ipAddress)

And log the HostName property returned by the call. Now to log the address of the page being requested, you can call:

Request.Url.ToString()

So to combine all these together, here is the code to build a visitors.log file:

// Track Visitors

string ipAddress = IpAddress();

string hostName = Dns.GetHostByAddress(ipAddress).HostName;

StreamWriter wrtr = new StreamWriter(Server.MapPath("visitors.log"), true);

wrtr.WriteLine(DateTime.Now.ToString() + " | " + ipAddress + " | " + hostName + " | " + Request.Url.ToString());

wrtr.Close();

The next question is what part of your ASP.NET page can you put the above code? There are two possible places, the first would be in the Application.BeginRequest event handler, the second can be in the Master page Load event. Here is how to do it in the Load event:

using System;

using System.Configuration;

using System.Net;

using System.IO;

namespace MyWebSite

{

public partial class DefaultMasterPage : System.Web.UI.MasterPage

{

protected void Page_Load(object sender, EventArgs e)

{

// Track Visitors

string ipAddress = IpAddress();

string hostName = Dns.GetHostByAddres(ipAddress).HostName;

StreamWriter wrtr = new StreamWriter(Server.MapPath("visitors.log"),true);

wrtr.WriteLine(DateTime.Now.ToString() + " | " + ipAddress + " | " + hostName + " | " + Request.Url.ToString());

wrtr.Close();

}

private string IpAddress()

{

string strIpAddress;

strIpAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

if (strIpAddress == null)

{

strIpAddress = Request.ServerVariables["REMOTE_ADDR"];

}

return strIpAddress;

}

}

}

Once you start getting some visitors, the result visitors.log file would look something like this:

4/2/2007 8:47:34 PM | 74.6.67.155 | lj612164.inktomisearch.com | http://www.mycsharpcorner.com/Post.aspx?postID=22

4/2/2007 8:53:05 PM | 66.249.66.35 | crawl-66-249-66-35.googlebot.com | http://www.mycsharpcorner.com/Default.aspx?categoryID=18

4/2/2007 9:02:41 PM | 66.249.66.35 | crawl-66-249-66-35.googlebot.com | http://www.mycsharpcorner.com/Default.aspx

4/2/2007 10:06:20 PM | 69.117.147.109 | ool-4575936d.dyn.optonline.net | http://www.mycsharpcorner.com/Post.aspx?postID=15

4/2/2007 10:12:23 PM | 72.30.216.102 | lm502014.inktomisearch.com | http://www.mycsharpcorner.com/Post.aspx?postID=22

4/2/2007 11:04:24 PM | 66.249.66.35 | crawl-66-249-66-35.googlebot.com | http://www.mycsharpcorner.com/Post.aspx?postID=15

4/2/2007 11:08:22 PM | 66.249.66.35 | crawl-66-249-66-35.googlebot.com | http://www.mycsharpcorner.com/Post.aspx?postID=23

Labels:

I found this piece of code on the internet, the author of this code is Tamer Oz.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Coderbuddy
{

public class CheckInternetConnection
{
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

public bool IsInternetConnectionAvailable()
{
int Desc;
return InternetGetConnectedState(out Desc, 0);
}
}
}

Labels:

The Following is a sample code to Extract Email addresses from a given string and store them into an array.I will give the code as Method, so that you can easily import it into your application.This code can be easily used to extract Email Id’s from a web page, just pass the HTML of the web page as the Text2Scrape.

This Class uses String arrays to store results

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Coderbuddy
{
public class ExtractEmails
{
private string s;
public ExtractEmails(string Text2Scrape)
{
this.s = Text2Scrape;
}

public string[] Extract_Emails()
{
string[] Email_List = new string[0];
Regex r = new Regex(@"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}", RegexOptions.IgnoreCase);
Match m;
//Searching for the text that matches the above regular expression(which only matches email addresses)
for (m = r.Match(s); m.Success; m = m.NextMatch())
{
//This section here demonstartes Dynamic arrays
if (m.Value.Length > 0)
{
//Resize the array Email_List by incrementing it by 1, to save the next result
Array.Resize(ref Email_List, Email_List.Length + 1);
Email_List[Email_List.Length - 1] = m.Value;
}
}
return Email_List;
}
}
}

The following code snippet is the same as the above one, the only difference is that this method saves the Extracted Email Id’s to a string list instead of an array, I think the following code is more effective and easy to code

This class uses List to store results, and these list are converted into arrays just before they are returned as arrays

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Coderbuddy
{
public class ExtractEmailLists
{
private string s;
public ExtractEmailLists(string Text2Scrape)
{
this.s = Text2Scrape;
}

public string[] Extract_Emails()
{
Regex r = new Regex(@"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}", RegexOptions.IgnoreCase);
Match m;
List results = new List();
for (m = r.Match(s); m.Success; m = m.NextMatch())
{
if (!(results.Contains(m.Value)))
results.Add(m.Value);
}
return results.ToArray();
}
}
}

Labels:

If you are working on a windows application, you may have have come accross a situation where you have to pass avariable between two forms.

Although there are many ways to do it, Sticking to my blog’s style, I will post the most easiest way to do it,

Steps to pass variables between forms

  • Lets assume that the Form that is passing the variable as Form1 and the one recieving them as Form2
  • Now Declare a public variable at the top of the form2 Class, so that it is global variable.
  • Lets assume that variable to be an int variable X
  • Now Initialise the Form2 class in Form1 as Form2 f2=new Form2()
  • Now assign the value you want to pass to the Form2 to X like,
  • f2.X=12; //You can pass any value here, make sure there is no data type mismatch
  • after X is assigned, open the Form Form2 as f2.ShowDialoag();
  • Now create an event for Form2 on load and Handle the Value of X
  • eg-: texBox1.Text=X.ToString()
  • You can now use the value of x in the Form2, you can use the same technique to pass any number of values, you can even use arrayas, objects, everything like this.

Labels:

Using System.Diagnostics we can know the processes currently running in our machine.

The code is quite simple. In the following demo, we will show all the processes running on your machine, plus a check if you are running Windows Live Messenger (a.k.a. MSN Messenger).


using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace CheckRunningProcesses
{
class Program
{
static void Main(string[] args)
{
const string messenger = "msnmsgr";
bool runningMessenger = false;

// Get Collection of running processes from Process Static method
Process[] processes = Process.GetProcesses();

// Scan processes in the obtained collection
foreach (Process p in processes)
{
Console.WriteLine(p.ProcessName);

if (p.ProcessName == messenger)
{
runningMessenger = true;
}
}

if (runningMessenger)
{
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("You have Windows Live Messenger (MSN) Running");
}

Console.ReadLine();
}
}
}


Note: The above code does not check whether you are signed in to the msn service. It just checks whether the MSN executable is running.

Labels:

Here are the differences between C# .NET const, readonly and static readonly fields.

Constants:

  • Static by default
  • Must have compilation-time value (i.e.: you can have "A"+"B" but cannot have method calls)
  • Can be used in attributes
  • Are copied into every assembly that uses them (every assembly gets a local copy of values)
  • Could be declared within functions
  • The compiler performs some optimization by not declaring any stack space for the field

Readonly instance fields:

  • Are evaluated when instance is created
  • Must have set value by the time constructor exits

Static readonly fields:

  • Are evaluated when code execution hits class reference (i.e.: new instance is created or static method is executed)
  • Must have evaluated value by the time static constructor is done
  • You really do not want to put ThreadStaticAttribute on these (since static constructor will be executed in one thread only and it will set value for its thread; all other threads will have this value uninitialized)

Class that has only constant or readonly instance fields is considered to be prepared for the concurrency challenges of parallel computing, since it has no mutable state.

BTW, there is a simple unit-test to enforce that your classes are immutable.

Labels:

Prior to .NET 2.0, the only way you could create your own collection which could be traversed using the 'foreach' construct was by having you class implementing the IEnumerable and IEnumerator Interfaces.

However since .NET 2.0 we have a new operator called 'yield'. This allows your class to be iterated by its consumer but without the need to implement the above-mentioned interfaces.

Let us see a small example of how this works:


// Our class does not implement any interface !
public class School
{
// Explicit initialization just for demo purposes !
private string[] studentNames = {"John", "Joan",
"Joanne", "Tony", "Peter"};

// The iterating method
public IEnumerator GetEnumerator()
{
foreach (string name in studentNames)
{
// yield return in action !
yield return name;
}
}
}


And now the code for the consumer:


class Program
{
static void Main(string[] args)
{
School NorthCoast = new School();

// How School's internal collection was iterated is hidden to the user
foreach (string student in NorthCoast)
{
Console.WriteLine(student);
}

Console.ReadLine();
}
}


As you can see it is easy to make your class iteratable without having to make it implmenet any interfaces.

The following is another example (inspired by an e-mail sent to me by one of the readers of this blog!):


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
MyYieldFileReader myYieldFileReader = new MyYieldFileReader();

foreach (string line in myYieldFileReader.ReadLine(@"C:\BuonVoyage.txt"))
{
Console.WriteLine(line);
}

Console.ReadLine();
}
}

class MyYieldFileReader
{
public IEnumerable ReadLine(string fileName)
{
using (StreamReader tr = new StreamReader(fileName))
{
while (!tr.EndOfStream)
{
yield return tr.ReadLine();
}
}
}
}
}


Finally, beware of the following constaints on the use of the 'yield' operator, as described in MSDN:


The yield statement can only appear inside an iterator block, which might be used as a body of a method, operator, or accessor. The body of such methods, operators, or accessors is controlled by the following restrictions:

Unsafe blocks are not allowed.

Parameters to the method, operator, or accessor cannot be ref or out.

A yield statement cannot appear in an anonymous method. For more information, see Anonymous Methods (C# Programming Guide).

When used with expression, a yield return statement cannot appear in a catch block or in a try block that has one or more catch clauses. For more information, see Exception Handling Statements (C# Reference).

Labels:

Introduction

Writing a C# ASP .NET web application which utilizes a database can create increasingly complex code. The more complex code gets, the more difficult it becomes to debug, maintain, and enhance. The Repository design pattern is a way of introducing architecture into your C# ASP .NET web application, which creates a clear layer of separation between your web forms and database accessible layers. The Repository pattern helps organize a web application to form a 3-tier architecture and provide loosly coupled classes, which can be reused in future C# ASP .NET web applications and easily updated.

In this article we'll implement a Repository Pattern for an example C# ASP .NET application which deals with planets in the solar system. The example application will contain 3-tiers, including the user interface, business logic layer, and database layer via the Repository design pattern.

A Repository Pattern is not THE Repository Pattern

Martin Fowler has described the traditional definition of the Repository design pattern as, "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects". This traditional definition describes the Repository design pattern as a class which closely maps to a database table, containing Insert, Update, Select, Delete, and collection functions for persisting a particular class object in the database. While this describes the traditional usage of the Repository pattern, many developers create their own summarized versions of the pattern, which are still equally effective. The main goal of the Repository design pattern is to decouple the 3-tier architecture of a C# ASP .NET application. In our example, we'll be creating our own implementation of the Repository Pattern. While our version may not contain the full set of CRUD functions, our implementation will still benefit from the Repository pattern's features of decoupled code and logical separation of layers.

Accessing the Database Old School Style

Many developers are familiar with accessing a database using code similar to the following in C# ASP .NET:

static void Main(string[] args)
{
SqlConnection MyConnection = new SqlConnection("YourConnectionString");

try
{
MyConnection.Open();

SqlCommand MyCommand = new SqlCommand("SELECT * FROM Planet", MyConnection);
SqlDataReader MyReader = MyCommand.ExecuteReader();
while (MyReader.Read())
{
// Read from the database and do things.
Planet planet = new Planet(Convert.ToInt32(MyReader["ID"].ToString()), MyReader["Name"].ToString(), Convert.ToInt32(MyReader["IsTerraformable"].ToString()));

Console.WriteLine("Planet " + planet.Name);
}

MyReader.Close();
}
catch (Exception excep)
{
}
finally
{
if (MyConnection != null && MyConnection.State == ConnectionState.Open)
{
MyConnection.Close();
}
}
}

Notice that the above code is quite straight-forward. We simply open a database connection, read a set of planets from the database table, and perform processing with the data. All of the code for accessing the database, performing any business logic, and displaying to the user interface is located in one big main function. While this code is easy to read, since everything is located in one place, this code may suffer from maintaince issues as the code expands over time. Consider what would happen if the user interface was much more complex that simply writing to the Console window. The code could drastically expand just to display the information to the user. To resolve this potential issue, the code can be pulled apart, separated in to layers, and re-organized using the Repository design pattern to provide a much more maintainable C# ASP .NET application.

A Cleaned Up Way of Accessing the Database with 3-Tiers

You can download the complete source code for this project by clicking here.

Using the Repository design pattern, we can actually completely separate the layers of concerns in the above example code, for accessing the planets in the solar system via the database. The code below shows an example of a new main method where the code for displaying to the user interface, processing business logic, and accessing the database are separated:

static void Main(string[] args)
{
// Load planets from the MSSQL repository.
PlanetBusiness planetBusiness = new PlanetBusiness(new MSSQLPlanetRepository());

List planetList = planetBusiness.GetPlanets();
foreach (Planet planet in planetList)
{
Console.WriteLine(planet.PlanetId + ". " + planet.Name);
}
}

Notice in the above code, there are no database accessible functions. We've also taken out any business logic processing that might occur after reading from the database. The only code included in our main method now is code which displays to the user interface. This clearly makes the job of maintaining the web application code much easier. Let's take a look at what's behind the scenes in the above example, which puts the pieces together to implement the Repository pattern.

We Can't Start Without a Type

Before we actually begin with the Repository pattern, we need to define a basic type library. In this library, we'll only have a single type called "Planet". This is a basic C# .NET class which has the required fields for working with a planet, most likely the same fields as the database table.

It's important to note that by creating your own light-weight type library, instead of using a potentially heavier ORM-generated one, you can be sure that your C# ASP .NET web application remains decoupled and completely separated in layers. This allows you the potential of swapping out different repositories at any time in the future, without having to change code in your main method. Since the main method deals with the Planet type, as long as the type doesn't change, the different Repositories can populate the Planet type as they wish and the main method will never know the difference.

public class Planet
{
public int PlanetId;
public string Name;
public bool IsTerraform;

public Planet()
{
}

public Planet(int planetId, string name, bool isTerraform)
{
PlanetId = planetId;
Name = name;
IsTerraform = isTerraform;
}
}

The above is a simple definition of the Planet type. It appears similar to the database table Planet, which contains an ID, Name, and boolean flag for Terraform. Any repository that we implement will populate the Planet type with data in their own way. Our main method, and other areas of our C# ASP .NET web application never need to know the details about how the repository actually populates the Planet type; they only concern themselves with using the type itself.

The Repository Pattern Starts With a Lonely Interface

As with most design patterns, the Repository pattern begins with a single interface, which outlines the methods that the data repository class will be able to perform. An example Repository interface is shown below:

public interface IPlanetRepository
{
List GetPlanets();
List GetStars();
}

In the above interface, we've simply defined two methods. One method fetches the planets in the solar system, while the other method fetches stars. One could easily expand this Repository pattern interface to include a full set of data access functions for working with a planet, such as Insert, Delete, Update, etc. For this example, we'll stick with these two basic functions for loading planets. The next step is to create a concrete repository class, which implements the interface.

An SQL Server Repository is Easy

Creating our first concrete repository is fairly simple. We'll simply implement the Repository pattern interface and write the required code for accessing the MSSQL database and populating the Planet types.

public class MSSQLPlanetRepository : IPlanetRepository
{
#region IPlanetRepository Members

public List GetPlanets()
{
// Simulate returning the list of data from the database.
List planetList = new List();

// SqlConnection code would actually go here, this is to keep things simple.
planetList.Add(new Planet(1, "Mercury", false));
planetList.Add(new Planet(2, "Venus", true));
planetList.Add(new Planet(3, "Earth", true));
planetList.Add(new Planet(4, "Mars", true));
planetList.Add(new Planet(5, "Jupiter", false));
planetList.Add(new Planet(6, "Saturn", false));
planetList.Add(new Planet(7, "Uranus", false));
planetList.Add(new Planet(8, "Neptune", false));
planetList.Add(new Planet(9, "Pluto", false));

return planetList;
}

public List GetStars()
{
// Simulate returning the list of data from the database.
List planetList = new List();

// SqlConnection code would actually go here, this is to keep things simple.
planetList.Add(new Planet(1, "Sun", false));

return planetList;
}

#endregion
}

The first item to note is that in this example, we're not actually reading from an MSSQL database. To keep the code simple, we're simply populating a list of Planets in the code. It is safe to assume that in place of the code adding planets to the array, would be code which loops through a DataReader and creates a planet for each read.

By returning test data from this repository, rather than reading from the actual database, we're actually showing off another advantage of the Repository design pattern. The advantage is the ability to easily create unit-testable methods in our applications, which return sample data without hitting the actual database. It's important to have consistent data in unit tests, whereas data from a live database may change over time. The Repository pattern allows us to easily create and swap in/out a unit test repository to verify business logic remains in-tact.

With the SQL Server repository implemented, we can now create our business logic layer.

The Business Layer Glues it Together

The simple .NET application we're creating in this article actually has minimal use for a business logic layer. However, in more complex C# ASP .NET applications, a business logic layer can greatly enhance the maintainability of a project. To optimally implement the Repository pattern, we'll need to create our business logic layer.

The business layer sits between the user interface and the Repository pattern data class. The business layer can be considered as a filter for the Repository pattern, calling the repository to obtain data and passing the processed results to the calling class (such as the main method in our user interface).

public class PlanetBusiness
{
IPlanetRepository _repository;

public PlanetBusiness(IPlanetRepository repository)
{
_repository = repository;
}

public List GetPlanets()
{
return _repository.GetPlanets();
}

public List GetStars()
{
return _repository.GetStars();
}

public List GetTerraformPlanets()
{
// Return the list of filtered data from the database.
List planetList = _repository.GetPlanets();

var results = from p in planetList
where p.IsTerraform == true
select p;

return results.ToList();
}
}

Notice in the above code, we've defined our business logic class to include a private instance of a planet Repository class. This allows our business class to implement any type of concrete planet repository class. For example, you could create PlanetBusiness to implement the MSSQL repository or you could create the class to implement a completely different repository, such as a test repository, Oracle, MySQL, etc. The important piece to note is that the member variable is a generic interface, which can implement any type of concrete planet repository.

The remainer of PlanetBusiness models the repository interface, with regard to the functions the calling class may want to use. We create methods for GetPlanets(), GetStarts(), and a new function called GetTerraformPlanets(), which actually calls the repository's method for GetPlanets(), but performs additional filtering of the data to return only those planets which can be terraformed.

Putting it All Together

With the layers defined, we can put the Repository pattern in action in our main method by creating an instance of the BusinessPlanet business logic layer, and passing in our desired instance of the concrete repository class.

static void Main(string[] args)
{
// Load planets from the MSSQL repository.
PlanetBusiness planetBusiness = new PlanetBusiness(new MSSQLPlanetRepository());

List planetList = planetBusiness.GetPlanets();
foreach (Planet planet in planetList)
{
Console.WriteLine(planet.PlanetId + ". " + planet.Name);
}
}

You can see in the above code how we've implemented the PlanetBusiness class with a concrete instance of the MSSQLPlanetRepository. When we call the generic business function GetPlants(), the business layer calls the MSSQL repository for the planet data. What if we wanted to move the database to Oracle? Would this effect the whole program?

Another Repository, Minimal Code

We can actually create another planet repository quite easily, effectively allowing us to change data sources, without touching any other areas of the application. This is an extremely powerful feature and the main reason to use the repository pattern. By limiting the areas of the web application that need code changes, we can make major alterations to the application with minimal chance for errors.

public class OracleRepository : IPlanetRepository
{
#region IPlanetRepository Members

public List GetPlanets()
{
// Simulate returning the list of data from the database.
List planetList = new List();

// OracleConnection code would actually go here, this is to keep things simple.
planetList.Add(new Planet(1, "Mercury", false));
planetList.Add(new Planet(2, "Venus", true));
planetList.Add(new Planet(3, "Earth", true));
planetList.Add(new Planet(4, "Mars", true));
planetList.Add(new Planet(5, "Jupiter", false));
planetList.Add(new Planet(6, "Saturn", false));
planetList.Add(new Planet(7, "Uranus", false));
planetList.Add(new Planet(8, "Neptune", false));
planetList.Add(new Planet(9, "Pluto", false));
planetList.Add(new Planet(10, "Planet X", false));

return planetList;
}

public List GetStars()
{
// Simulate returning the list of data from the database.
List planetList = new List();

// OracleConnection code would actually go here, this is to keep things simple.
planetList.Add(new Planet(1, "Sun", false));
planetList.Add(new Planet(2, "Alpha Centauri", false));

return planetList;
}

#endregion
}

The above code defines another planet repository, this time working with an Oracle database. Again, the data loaded is hard-coded for simplicity, but would actually be loading from a database. To show differences in the data, the hard-coded values are slightly different than the MSSQL repository.

Calling Another Repository is the Same

To call our newly created Oracle planet repository, we simply implement the new repository in our business class, as follows:

static void Main(string[] args)
{
// Load planets from the Oracle repository.
PlanetBusiness planetBusiness = new PlanetBusiness(new OraclePlanetRepository());

List planetList = planetBusiness.GetPlanets();
foreach (Planet planet in planetList)
{
Console.WriteLine(planet.PlanetId + ". " + planet.Name);
}
}

With this one small change, we've instantly changed the functionality of the C# ASP .NET web application from working with planets in an SQL Server database to working with an Oracle database. Further, for unit testing, we could even create a unit-testable repository with no database access at all.

Unit Testing is Boring, But at Least the Repository Makes it Easy

When performing unit testing against a live database, values can often change, making it difficult to verify that a variable holds a specific value. To resolve this type of unit-testing issue, we can create a special unit test Repository, which contains static data or hard-coded values. The data returned would then be processed by the business layer and can be unit tested accordingly.

public class TestRepository : IPlanetRepository
{
#region IPlanetRepository Members

public List GetPlanets()
{
// Simulate returning the list of data from the database.
List planetList = new List();

planetList.Add(new Planet(1, "Earth", true));
planetList.Add(new Planet(2, "Test Planet", true));

return planetList;
}

public List GetStars()
{
// Simulate returning the list of data from the database.
List planetList = new List();

planetList.Add(new Planet(1, "None", false));

return planetList;
}

#endregion
}

In the above code we've defined yet another planet repository, which loads a set of hard-coded data. This repository makes it easy to unit test and verify proper functioning of the business logic and layers.

Combining Repositories For Some Action

To really see the power behind the repository pattern, lets implement all three repository types in the main method and see how the different data loads:

static void Main(string[] args)
{
// Load planets from the MSSQL repository.
PlanetBusiness planetBusiness = new PlanetBusiness(new MSSQLPlanetRepository());
TestPlanets(planetBusiness);

// Load planets from the Oracle repository.
planetBusiness = new PlanetBusiness(new OracleRepository());
TestPlanets(planetBusiness);

// Load planets from the Test repository.
planetBusiness = new PlanetBusiness(new TestRepository());
TestPlanets(planetBusiness);

Console.ReadKey();
}

private static void TestPlanets(PlanetBusiness planetBusiness)
{
// Basic driver class to test our planet business class and display output.
Console.WriteLine();
Console.WriteLine("Planets:");
Console.WriteLine();

List planetList = planetBusiness.GetPlanets();
foreach (Planet planet in planetList)
{
Console.WriteLine(planet.PlanetId + ". " + planet.Name);
}

Console.WriteLine();
Console.WriteLine("Terraformable Planets:");
Console.WriteLine();

planetList = planetBusiness.GetTerraformPlanets();
foreach (Planet planet in planetList)
{
Console.WriteLine(planet.PlanetId + ". " + planet.Name);
}
}

The above code has combined the different planet repositories into a single main method. The data displayed to the user interface via the TestPlanets() method will change depending on which concrete repository is implemented in the PlanetBusiness class.

We can actually take this one step further with .NET reflection to allow us to implement a concrete repository at run-time without re-compiling code.

Using Reflection to Super-Charge your Repository Pattern

Until now, the previous examples showed static pre-compile time implementations of the repository pattern. We implemented an MSSQL, Oracle, and Test planet repository. However, each time we changed the repository we needed to re-compile and run the application. In a live enviornment, this may not be optimal, especially when automatic unit testing scripts may be running. In this case, we can use C# .NET reflection to automatically implement the desired concrete repository at run-time, by reading the web.config.

To begin, simply add the following code to your web.config file, which defines the concrete repository class and assembly file to load the repository from.






Then modify the main method to implement this concrete repository in the business layer, as follows:

static void Main(string[] args)
{
// Load planets from the default repository as specified in the web.config. Allows for changing the repository at run-time, without changing code!
Type obj = Type.GetType(ConfigurationManager.AppSettings["DefaultRepository"]);
ConstructorInfo constructor = obj.GetConstructor(new Type[] { });
IPlanetRepository defaultRepository = (IPlanetRepository)constructor.Invoke(null);

PlanetBusiness planetBusiness = new PlanetBusiness(defaultRepository);
TestPlanets(planetBusiness);

Console.ReadKey();
}

In the above code, we're first obtaining the type for the repository by reading the web.config and locating the class. We then invoke the class's constructor to create an instance of the concrete repository. This is the same is calling: new MSSQLPlanetRepository(). We can then assign the concrete repository to the PlanetBusiness business logic layer as in the previous examples.

You can see that by adding reflection into the process, you could easily expand the capability of your architecture to support loading multiple repositories at run-time for different enviornments, such as automatic unit testing, QA server testing, and production scenerios.