Book Image

Instant .NET 4.5 Extension Methods How-to

By : Shawn Ricardo Mclean
Book Image

Instant .NET 4.5 Extension Methods How-to

By: Shawn Ricardo Mclean

Overview of this book

.NET extension methods is an essential feature to know and understand for all .NET developers. Usage of extension methods is found in applications ranging from small to large scale enterprise systems built using the .NET framework. Create and use extension methods the correct way to save your development time and maintainability costs. Instant .NET 4.5 Extension Methods How-to is a practical, hands-on guide that provides you with a number of clear, step-by-step exercises that will help you take advantage of the real power that is behind extension methods and gives you good knowledge of how to use them in your .NET applications. This book covers how to create, write, and use different types of extension methods. It will take you through a number of clear, practical recipes that will help you take advantage of the power of extension methods in the quickest possible way. You will also learn exactly how to create extension methods on strings, interfaces, classes such as IQueryable and IEnumerable, and so on. You will write them from scratch and then use them practically in your application. You will also learn the most suitable scenarios for using these extension methods.You will learn everything you need to know about creating your own extension methods and using them and other external extension methods.
Table of Contents (6 chapters)

Extension methods on IQueryable (Become an expert)


IQueryable is used to operate mainly on databases. IQueryable<T> are an extension from IEnumerable<T>, hence, we can call all extensions and methods of IEnumerable<T>. A query using IQueryable can be built up on over time, before it hits the database. The query is executed once you execute an eager function such as ToList(), looping the data or attempting to use the values. IQueryable is used by providers such as LINQ to entities or LINQ to SQL.

Getting ready

Refer to the IQueryableExtensions.cs file in the ExtensionMethods.Library project for the extension methods. The models are located in Models/PagedList.cs and Models/IPagedList.cs. These methods are used in the IQueryableExtensionTests.cs file in the ExtensionMethods.Tests project.

How to do it...

The following code snippet shows a general use of extension methods on IQueryables:

public static User ByUserId(this IQueryable<User> query, int userId)
{
    return query.First(u => u.UserId == userId);
}

The following code snippet is a paged list class for pagination of data:

public class PagedList<T> : List<T>, IPagedList
{
    public PagedList(IQueryable<T> source, int index, int pageSize)
    {
        this.TotalCount = source.Count();
        this.PageSize = pageSize;
        this.PageIndex = index;
        this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
    }    
        
    public PagedList(List<T> source, int index, int pageSize)
    {
        this.TotalCount = source.Count();
        this.PageSize = pageSize;
        this.PageIndex = index;
        this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
    }
    
    public int TotalCount      
    { 
        get; set; 
    }
        
    public int PageIndex       
    { 
        get; set; 
    }
        
    public int PageSize 
    { 
        get; set; 
    }

    public bool IsPreviousPage 
    { 
        get 
        {
            return (PageIndex > 0);
        }
    }    
    public bool IsNextPage 
    { 
        get
        {
            return (PageIndex * PageSize) <=TotalCount;
        } 
    }        
}

The following code snippet is the extension method that executes and converts the query to the PagedList object:

public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
{
    return new PagedList<T>(source, index, pageSize);
}

The following code snippet shows how we use these extension methods:

[TestMethod]
public void UserByIdReturnsCorrectUser()
{
    var query = new List<User>
                    {
                        new User {UserId = 1},
                        new User {UserId = 2}
                    }.AsQueryable();

    var user = query.ByUserId(1);

    Assert.AreEqual(1, user.UserId);
}

[TestMethod]
public void PagedList_Contains_Correct_Number_Of_Elements()
{
    var query = new List<int>{1,2,3,4,5,6,7,8,9,10}.AsQueryable();

    var pagedList = query.ToPagedList(0, 5);

    Assert.AreEqual(5, pagedList.Count);
    Assert.AreEqual(10, pagedList.TotalCount);
}

How it works...

The first code snippet ByUserId is the most commonly used type of extension method for IQueryable types. An alternative to this method is to use the repository pattern and add a method of getting a user by the Id. But sometimes, we will expose the query to lower levels of the app such as the service layer where we might need to use this feature at multiple places, hence refactoring that logic into an extension method makes perfect sense.

This extension method evaluates and executes the query immediately due to requesting a single value using the First() method:

query.First(u => u.UserId == userId);

The second code snippet gives us a PagedList model which becomes a valuable class when working with grids or pagination. The constructor accepts an IQueryable or IList and converts that data into a paged list. Take note of the line in which we evaluate the source by calling ToList(). This line executes the query on the provider:

this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());

In the code snippets using these extension methods, we have created a list and cast it to an IQueryable type. This is purely for the purpose of demonstration. In a real application, the query would be coming from a LINQ to SQL or entities context, which is in charge of executing the query against a database.

We need to be careful of how extension methods on IQueryable are written. A poorly written query will result in unexpected behavior, such as premature query execution. If the extension method is simply building up the query (using method chaining), ensure that the query is not evaluated inside the method. If the query is evaluated and executed before the method finishes, any other use of the query outside of the extension method will result in operating on the data in memory.

In this recipe, you have learned a few tricks and caveats when using extending IQueryable.