Extension Method

Extension method is a feature in c# 3.0, which allows developer to add functionality in existing class without modifying the existing class or recompiling the existing class or extending the existing class.

  1. It is a new feature of c#3.0
  2. Extension method enables to add new methods to existing type. It does not need creation of derived type to existing type, modifying the original type or recompiling the original type.
  3. It provides ability to programmer to add new methods to existing type.
  4. It can be used to add new methods to existing .Net core classes.
    It is defined as a static method but called with syntax of instance method.
  5. If there is a member method in type class with the same name of extension method then member method will get precedence over extension method.

    For example Show method is member method of Message class. So if there is any extension method called Show on type Message class is created, always Show member method will get precedence over Show extension method for the type Message.
    Compiler Signature

 static class Extensions {
      public static IEnumerable<T> Where<T>(this IEnumerable<T> sequence, Predicate<T> predicate) {
                      foreach (T item in sequence) {
                                                       if (predicate(item))  {
                                                                                      yield  return item;
}}}}

  1. The method is static
  2. The first parameter is decorated with modifier “this” .
  3. First parameter is called as Instance Parameter.
  4. A compile time error will encountered to use this modifer with any other parameter than instance parameter.
  5. No other modifers like ref, out etc are allowed with “this” modifer or instance parameter.
  6. The instance parameter can not be a pointer type.
  7. The method is public .
  8. The instance parameter can not have the type of the type parameter. The below is not possible.

    public static int Obj<T> (this T param)

Restrictions

  1. It could only access public memebers of the target type.
  2. If an extension method conflicts with a member method of target type , always member method is get invoked instead of extension method.

Implementation and Calling

Step1 : Define a static visible class to contain Extension method. 

Step2: Implement the Extension method as static method. 

Step 3: The First parameter of method specifies the type method works on 

Step4 : The First parameter must be preceded by “this” modifer. 

Step 5: At the client code add namespace of extension method with using directive.

 Examples

  1. In first example, I will add an Extension method to existing String class. This extension method will remove all the vowel form the string  

  1. Modify the class with modifier with public and static of the class extensionmethodcontainer. 
  2. Add a extension method with below signature. The First parameter String specifies that this is extension method on the type String.

 public static String RemoveVowel(this String s)

The full code to remove vowel from input string is written in the Extension method.

 

    1 using System;

    2 

    3 using System.Collections.Generic;

    4 

    5 using System.Linq;

    6 

    7 using System.Text;

    8 

    9 namespace ExtensionMethodSample

   10 {

   11 public static class extensionmethodcontainer

   12 {

   13 

   14 public static String RemoveVowel(this String s)

   15 {

   16 string[] vowels = new

   17 

   18 string[] { “A”, “E”, “I”, “O”, “U” };

   19 

   20 if (string.IsNullOrEmpty(s))

   21 return string.Empty;

   22 

   23 List<char> chars = new List<char>(s.ToCharArray());

   24 for (int i = chars.Count – 1; i >= 0; i–)

   25   {

   26        for (int j = 0; j < vowels.Length; j++)

   27             {

   28 

   29                     if (chars[i].ToString().ToLower() == vowels[j].ToLower())

   30 

   31                         chars.RemoveAt(i);

   32              }

   33             }

   34 

   35 return new string(chars.ToArray());

   36 

   37 }

   38 

   39 }

   40 

   41 }

   42 

  1. Client code is here Main class
  2. In main class, user is inputting the string and RemoveVowel extension method is being called on the input string to remove vowel from the string. 

    Note:

    1. Here both Extension method and client is in same namespace, so there is no need to include namespace of the extension method.
    2. Extension method is called as any other member method


      resultString = str.RemoveVowel();

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 namespace ExtensionMethodSample

    6 {

    7 class Program

    8 {

    9 static void Main(string[] args)

   10 {

   11 String resultString;

   12 

   13 Console.WriteLine(“Enter Input String to Remove all Vowel using Extension Method \n”);

   14 

   15 String str = Console.ReadLine();

   16 

   17 Console.WriteLine(“After Removing Vowel Input String is \n”);

   18 

   19 resultString = str.RemoveVowel();

   20 

   21 Console.WriteLine(resultString);

   22 

   23 Console.ReadKey();

   24 }

   25 }

   26 }

   27 }

   28 


 

Happy Coding

Picture Gallery for Windows 7 Phone using WCF REST Service

Objective

In this article I will give you walkthrough of creating a Picture Gallery for Windows 7 phone. I will show how to fetch images from server using WCF REST service. The final output would be like below

Please read this article before going through this article.

In this article, majorly I am going to show you two things

  1. How could we process image from file system of server using REST service and return the jpeg format as response.
  2. How could we consume REST service in Windows 7 phone application? And how could we de- serialize stream at in windows 7 phone application.

Working Diagram

 

If you see above diagram, we are going to perform below steps.

  1. Image files are at some certain location of server.
  2. Using .Net file handling classes, we will fetch those image files.
  3. Using WCF REST service we will return image in form of stream.
  4. We will test the REST service in browser.
  5. We will consume the REST service in Windows 7 phone application.

Step 1

On your server or hard disk of your development machine put some images in a particular folder of a particular drive. I am putting some images inside IMAGES folder of D drive.

I do have below images inside D:\Images folder

Step 2

Accessing the File System in service

To access the files and work with file system in .Net we need to add namespace System.IO .

Now if we want to access name of all the files inside a particular folder, we need to access all the files using instance of DirectoryInfo class. So the code to return all the file names is as below,

In above code

  1. I am creating instance of List of string.
  2. I am creating instance of DirectoryInfo class. In constructor, I am passing the location of the directory.
  3. Using GetFiles method of DirectoryInfo class, I am fetching all the files in that particular directory.
  4. I am iterating through FileInfo array and fetching name of all the files.
  5. I am splitting the file name over dot(.) because I do not want extension of the file to be added as file name.
  6. Finally I am adding the file names in list of string and returning it.  

Step 3

In this step, I will create a WCF REST Service. This Service will return Files name and images as stream. So to create WCF REST Service follows below steps

Step 3A

Create a WCF application. To create a new application File -> New -> Web-> WCF Service Application.

Step 3B

Remove all the default code created by WCF. Remove code from IService 1 interface and Service1 class. Remove the code from Web.Config also. Open Web.Config and remove System.Servicemodel codes.

Step 3C

Right click on Service1.svc select View markup and add below code

<%@
ServiceHost
Language=”C#”
Debug=”true”
Service=”FetchingImageinBrowser.Service1″
CodeBehind=”Service1.svc.cs”
Factory=”System.ServiceModel.Activation.WebServiceHostFactory”
%>

 Step 3D
Now I will create Contracts. There would be two service methods. One would be returning FilesName and other would be returning Stream.

 If you see the above Service Contract, you will find

  1. GetImage operation contract is taking file name as input parameter and returning stream. This service method will be accessed through default URI of hosting server slashed with GetImageand then slashed with input parameter.

    http://localhost:53767/Service1.svc/GetImage/MyImage

  2. GetFIlesName operation contract is returning all the files name of a particular directory. This service method will be accessed through below URL.

    http://localhost:53767/Service1.svc/GetFilesName

    In both above case service is hosted on local server on the port 53767.

Step 3E

In this method we will define the service. Already in step 2 I have shown you, how we could fetch name of all the files from a particular directory. The other service method returning stream is below.

If you read the above code, I am opening the input file in FileStream. Then using WebOperationContext class, I am setting the Outgoing response as Image and Jpeg.

For your reference, the full source code for the service is as below

Contract (IService1.cs)

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Runtime.Serialization;

    5 using System.ServiceModel;

    6 using System.ServiceModel.Web;

    7 using System.Text;

    8 using System.IO ;

    9 namespace FetchingImageinBrowser

   10 {

   11     [ServiceContract]

   12     public interface IService1

   13     {

   14 

   15         [OperationContract]

   16         [WebGet(UriTemplate = "GetImage/{imageName}",

   17             RequestFormat = WebMessageFormat.Xml,

   18             ResponseFormat = WebMessageFormat.Xml)]

   19         Stream GetImage(string imageName);

   20 

   21         [OperationContract]

   22         [WebGet(UriTemplate = "GetFilesName")]

   23         List<String> GetFilesName();

   24     }  

   25 }

   26   

 

Service Definition (Service1.svc.cs)

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Runtime.Serialization;

    5 using System.ServiceModel;

    6 using System.ServiceModel.Web;

    7 using System.Text;

    8 using System.IO ;

    9 namespace FetchingImageinBrowser

   10 {

   11     public class Service1 : IService1

   12     {

   13 

   14         public Stream GetImage(string imageName)

   15 

   16         {

   17             FileStream fs = null;

   18             string fileName = string.Format(@”D:\Images\{0}.jpg”, imageName);

   19             fs = File.OpenRead(fileName);

   20             WebOperationContext.Current.OutgoingResponse.ContentType = “image/jpeg”;

   21             return fs;

   22 

   23         }

   24 

   25         public List<String> GetFilesName()

   26         {

   27             List<String> lstFileName = new List<string>();

   28             DirectoryInfo dir = new DirectoryInfo(@”D:\Images”);

   29             FileInfo[] files = dir.GetFiles();

   30             foreach (FileInfo f in files)

   31             {

   32                 lstFileName.Add(f.Name.Split(“.”.ToCharArray())[0]);

   33             }

   34             return lstFileName;

   35         }

   36     }

   37 }

   38 

Step 4
Run the service. By default service will be hosted in Cassini server. We can test this service in browser because it is REST service.

When you run URL http://localhost:53767/Service1.svc/GetFilesName , You will get below output. All the files inside the folder is listed in the browser.


When you run URL http://localhost:53767/Service1.svc/GetImage/MyImage, you will get MYImage (name of the image file) in browser like below


So far, we have created the service and tested successfully in the browser. So we are all set to consume the service in Windows 7 Phone application.

Step 5

Since service is up and running, now we can consume the service anywhere. In this tutorial we are going to consume the service in Windows 7 Phone application.

Step 5A

Create a new Windows Phone Application. From Silverlight for Windows Phone tab select Windows Phone Application project type.

 

Step 5B

In this step, we will design the page.

 

  1. I have divided the Content Grid in two rows with the ratio of 3:1
  2. In first row put a stack panel.
  3. Inside stack panel put a Button and a Combo box.
  4. Register selection changed event with Combo box.
  5. In second row put a Image control.
  6. Set the height and width of the image as Auto.

Step 5C

In this step we will write the code behind to consume the service.

On click event of button, we will call the service and get the entire files name inside the particular directory.

  1. In above code, I am using WebClient to do asynchronous call to REST service.
  2. If you see closely in string I am assigning the same URL we tested in step 4 to fetch file names.
  3. Using DataContractSerializer class we are creating an instance and passing type we are going to de serialize in constructor.
  4. We are reading all the objects in instance of DataContractSerializer and explicitly typecasting it to List<String>.
  5. One by one we are iterating to list and adding each filename (string) as item of combo box.

On changed event of combo box, we will pass the image name as selected item in combo box and fetch the image and set that image as source of image control.

  1. In above code, I am using WebClient to do asynchronous call to REST service.
  2. If you see closely in string I am assigning the same URL we tested in step 4 to fetch particular image.
  3. I am creating instance of BitmapImage.
  4. Setting the source of the image as response from the service.
  5. Setting the source of image control as instance of BitmapImage.

For your reference whole source code is as below,

MainPage.Xaml

   1: <;phoneNavigation:PhoneApplicationPage 

   2:     x:Class="RESTServiceConsuming.MainPage"

   3:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   4:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   5:     xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"

   6:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

   7:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   8:     mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"

   9:     FontFamily="{StaticResource PhoneFontFamilyNormal}"

  10:     FontSize="{StaticResource PhoneFontSizeNormal}"

  11:     Foreground="{StaticResource PhoneForegroundBrush}">;

  12:     <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">

  13:         <;Grid.RowDefinitions>

  14:             <;RowDefinition Height="Auto"/>

  15:             <;RowDefinition Height="*"/>

  16:         <;/Grid.RowDefinitions>       

  17:         <;Grid x:Name="TitleGrid" Grid.Row="0">

  18:             <;TextBlock Text="Windows 7 Phone" x:Name="textBlockPageTitle" Style="{StaticResource PhoneTextPageTitle1Style}"/>

  19:             <;TextBlock Text="Picture Gallery" x:Name="textBlockListTitle" Style="{StaticResource PhoneTextPageTitle2Style}"/>

  20:         <;/Grid>       

  21:         <;Grid x:Name="ContentGrid" Grid.Row="1">

  22:             <;Grid.RowDefinitions>

  23:                 <;RowDefinition Height="*" />

  24:                 <;RowDefinition Height="3*" />

  25:             <;/Grid.RowDefinitions>

  26:             <;StackPanel Orientation="Horizontal" Margin="0,0,0,31">               

  27:                 <;Button x:Name="myButton" Height="50" Content="Get FileNames" />            

  28:                 <;ComboBox x:Name="cmbName" Height="50" 

  29:                           SelectionChanged="cmbName_SelectionChanged"

  30:                           Margin="21,0,10,0"

  31:                           Foreground="Black" Width="211" />;

  32:             </StackPanel>

  33:             <;Image Grid.Row="1" x:Name="myImage" 

  34:                    Height="Auto" Width="Auto"

  35:                    ScrollViewer.HorizontalScrollBarVisibility="Auto"

  36:                    ScrollViewer.VerticalScrollBarVisibility="Auto" />;          

  37:         </Grid>

  38:     <;/Grid>   

  39: </phoneNavigation:PhoneApplicationPage>

 
MainPage.Xaml.cs

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Net;

    5 using System.Windows;

    6 using System.Windows.Controls;

    7 using System.Windows.Documents;

    8 using System.Windows.Input;

    9 using System.Windows.Media;

   10 using System.Windows.Media.Animation;

   11 using System.Windows.Shapes;

   12 using Microsoft.Phone.Controls;

   13 using System.Xml;

   14 using System.Runtime.Serialization;

   15 using System.Windows.Media.Imaging;

   16 

   17 

   18 namespace RESTServiceConsuming

   19 {

   20     public partial class MainPage : PhoneApplicationPage

   21     {

   22         public MainPage()

   23         {

   24             InitializeComponent();

   25             SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;

   26             myButton.Click += new RoutedEventHandler(myButton_Click);         

   27 

   28 

   29         }

   30 

   31         void myButton_Click(object sender, RoutedEventArgs e)

   32         {

   33             cmbName.Items.Clear();

   34             cmbName.SelectedIndex = -1;

   35 

   36             string strUriFilesName = http://localhost:53767/Service1.svc/getfilesName&#8221;;

   37             WebClient proxy1 = new WebClient();

   38             proxy1.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy1_OpenReadCompleted);

   39             proxy1.OpenReadAsync(new Uri(strUriFilesName));

   40 

   41         }

   42 

   43         void proxy1_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)

   44         {

   45 

   46             DataContractSerializer ds = new DataContractSerializer(typeof(List<string>));

   47             List<string> lstFileName = (List<string>) ds.ReadObject(e.Result);

   48             foreach (string file in lstFileName)

   49             {

   50                 cmbName.Items.Add(file);

   51             }

   52 

   53         }  

   54 

   55 

   56         private void cmbName_SelectionChanged(object sender, SelectionChangedEventArgs e)

   57         {

   58 

   59             if (cmbName.SelectedIndex != -1)

   60             {

   61                 string imageName = cmbName.SelectedItem.ToString();

   62                 WebClient proxy = new WebClient();

   63                 string strUriImage = http://localhost:53767/Service1.svc/getImage/&#8221; + imageName;

   64                 proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(proxy_OpenReadCompleted);

   65                 proxy.OpenReadAsync(new Uri(strUriImage));

   66             }

   67         }

   68 

   69         void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)

   70         {

   71 

   72             BitmapImage img = new BitmapImage();

   73             img.SetSource(e.Result);

   74             myImage.Source = img;

   75 

   76 

   77         }

   78 

   79     }

   80 }


Now we are ready to run our application. Press F5 and run the application in emulator. After running you will get first screen. Press button to populate the entire files name in the combo box. After selecting a particular file that image would get display as third screen.

I hope this article was informative. Happy Coding.