Extension Methods
Contents
Introduction
Extension methods are a new feature in C# 3.0. An extension method enables us to add methods to existing types without creating a new derived type, recompiling, or modify the original types. We can say that it extends the functionality of an existing type in .NET. An extension method is a static method to the existing static class. We call an extension method in the same general way; there is no difference in calling.
Feature and Property of Extension Methods
The following list contains basic features and properties of extension methods:
- It is a static method.
- It must be located in a static class.
- It uses the "this" keyword as the first parameter with a type in .NET and this method will be called by a given type instance on the client side.
- It also shown by VS intellisense. When we press the dot (.) after a type instance, then it comes in VS intellisense.
- An extension method should be in the same namespace as it is used or you need to import the namespace of the class by a using statement.
- You can give any name for the class that has an extension method but the class should be static.
- If you want to add new methods to a type and you don't have the source code for it, then the solution is to use and implement extension methods of that type.
- If you create extension methods that have the same signature methods as the type you are extending, then the extension methods will never be called.
Using the Code
We create an extension method for a string type so string will be specified as a parameter for this extension method and that method will be called by a string instance using the dot operator.
In the above method WordCount(), we are passing a string type with this so it will be called by the string type variable, in other words a string instance.
Now we create a static class and two static methods, one for the total word count in a string and another for the total number of characters in a string without a space.
using System;
namespace ExtensionMethodsExample
{
public static class Extension
{
public static int WordCount(this string str)
{
string[] userString = str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries);
int wordCount = userString.Length;
return wordCount;
}
public static int TotalCharWithoutSpace(this string str)
{
int totalCharWithoutSpace = 0;
string[] userString = str.Split(' ');
foreach (string stringValue in userString)
{
totalCharWithoutSpace += stringValue.Length;
}
return totalCharWithoutSpace;
}
}
}
Now we create an executable program that has a string as an input and uses an extension method to count the total words in that string and the total number of characters in that string then show the result in a console screen.
using System;
namespace ExtensionMethodsExample
{
class Program
{
static void Main(string[] args)
{
string userSentance = string.Empty;
int totalWords = 0;
int totalCharWithoutSpace = 0;
Console.WriteLine("Enter the your sentance");
userSentance = Console.ReadLine();
//calling Extension Method WordCount
totalWords = userSentance.WordCount();
Console.WriteLine("Total number of words is :"+ totalWords);
//calling Extension Method to count character
totalCharWithoutSpace = userSentance.TotalCharWithoutSpace();
Console.WriteLine("Total number of character is :"+totalCharWithoutSpace);
Console.ReadKey();
}
}
}
http://extensionmethod.net/ is a good source for extension methods.
Creating HTML Helpers with Extension Methods
Helpers\LabelExtensions.cs
using System;
using System.Web.Mvc;
namespace MvcApplication1.Helpers
{
public static class LabelExtensions
{
public static string Label(this HtmlHelper helper, string target, string text)
{
return String.Format("<label for='{0}'>{1}</label>", target, text);
}
}
}
Usage
<%= Html.Label("lastName", "Last Name:") %>
Custom HTML User Control in ASP.Net MVC Razor View Engine
In ASP.NET we create user controls as .ascx files. But in ASP.NET MVC it is a little bit different. In MVC we have multiple ways to do it. We have partial views, HtmlHelper and so on. HtmlHelper is a class for rendering HTML controls in a view.
public static class LoginStatusControl
{
public static MvcHtmlString LoginStatus(this HtmlHelper htmlHelper, string CssClass)
{
StringBuilder sb = new StringBuilder();
sb.Append("<ol class='" + CssClass + "'>");
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
sb.Append("Hello ");
sb.Append(System.Web.HttpContext.Current.User.Identity.Name );
sb.Append("!");
}
else
{
sb.Append("Welcome");
}
sb.Append("</ol>");
return MvcHtmlString.Create(sb.ToString());
}
}
Here we will pass the CSS class to our control. If the user is authentic then it will show, for example, ”Hello Tom !“. Otherwise only the welcome message will be displayed. Then I have implemented this control in my layout.
<div class="row">
<div class="col-xs-3">
@Html.LoginStatus("breadcrumb")
</div>
</div>
it provides a welcome / username label on top of the page.
Custom ComboBox
Code
namespace CustomHtmlHelpers.CustomHelpers
{
public static class CustomDropdDownList
{
//This overload is extension method that accepts two parameters i.e. name and Ienumerable list of values to populate.
public static MvcHtmlString Custom_DropdownList(this HtmlHelper helper ,string name, IEnumerable<SelectListItem> list)
{
//This method in turns calls below overload.
return Custom_DropdownList(helper, name, list, null);
}
//This overload is extension method accepts name, list and htmlAttributes as parameters.
public static MvcHtmlString Custom_DropdownList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> list, object htmlAttributes)
{
//Creating a select element using TagBuilder class which will create a dropdown.
TagBuilder dropdown = new TagBuilder("select");
//Setting the name and id attribute with name parameter passed to this method.
dropdown.Attributes.Add("name", name);
dropdown.Attributes.Add("id", name);
//Created StringBuilder object to store option data fetched oen by one from list.
StringBuilder options = new StringBuilder();
//Iterated over the IEnumerable list.
foreach (var item in list)
{
//Each option represents a value in dropdown. For each element in the list, option element is created and appended to the stringBuilder object.
options = options.Append("<option value='" + item.Value + "'>" + item.Text + "</option>");
}
//assigned all the options to the dropdown using innerHTML property.
dropdown.InnerHtml = options.ToString();
//Assigning the attributes passed as a htmlAttributes object.
dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
//Returning the entire select or dropdown control in HTMLString format.
return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}
}
}
In the above class we have created two overloads as per our convenience.
Overload 1 : The first overload accepts two parameters i.e. name and list. The name parameter is used to set name and id attribute. The list parameter is used to populate the dropdown. This method is extension method and accepts object of HtmlHelper class. The first parameter adds this overload to System.Web.MVC namespace. On view we can access this method using @html. This overload in turn calls another overload.
Overload 2 : The second overload accepts three parameters i.e. name, list and htmlAttributes object. The name parameter is used to set the name and id attribute. The list is used to populate the dropdown. The htmlAttributes object contains other attributes passed.
We have used TagBuilder class to create a select element which renders a dropdown. We are then iterating over the list and creating option element for each item in the list. We have appended the option elements in string format to object of StringBuilder class. This object is then added to the select element using innerHTML property. We have also assigned other attributes passed using htmlAttributes object.
View :
@model CustomHtmlHelpers.Models.Register
@{
ViewBag.Title = "About Us";
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "Jack Wilshere", Value = "10" });
list.Add(new SelectListItem { Text = "Thierry Henry", Value = "14" });
list.Add(new SelectListItem { Text = "Cesc Fabregas", Value = "04" });
list.Add(new SelectListItem { Text = "Santi Cazorla", Value = "19" });
list.Add(new SelectListItem { Text = "Tomas Rosicky", Value = "08" });
}
<h2>About</h2>
<p>
@Html.Custom_DropdownList("Players", list)
@Html.Custom_DropdownList("Players", list, new { multiple = "multiple"})
</p>
Rendered HTML:
<select id="Players" name="Players"> <option value='10'>Jack Wilshere</option> <option value='14'>Thierry Henry</option> <option value='04'>Cesc Fabregas</option> <option value='19'>Santi Cazorla</option> <option value='08'>Tomas Rosicky</option> </select> <select id="Players" multiple="multiple" name="Players"> <option value='10'>Jack Wilshere</option> <option value='14'>Thierry Henry</option> <option value='04'>Cesc Fabregas</option> <option value='19'>Santi Cazorla</option> <option value='08'>Tomas Rosicky</option> </select>
Using Dependency Injection
Please see StructureMap Implementation
