F#– WPF Component Development

This post will only deal about using F# for WPF custom component development; it is considered that the user has already knowledge about WPF custom control development.

The current F# support for VS2010 is lagging in some ways,

· Can’t create a folder, this directly affects the way we can define the generic.xaml file.

· XAML -> BAML conversion with MSBuild task

We can do workarounds in both the cases and make component development using F# language and that is what we are going to discuss here. If there is any other better way to go for it, do let me know in your comments.

Creating Folders in an F# project

Till the F# team include this support in VS2010 we need to do the below workaround,

· Edit the .fsproj in Notepad.

· Add the below line in <ItemGroup>

.fsproj code

<Resource Include="Themes\generic.xaml" />

<Compile Include=”NewFolder\somefile.fs” />

XAML to BAML conversion through code

WPF has an API Application.LoadComponent(Uri) which loads a resource, although it is a bit slow. For a WPF component to load its inner template, it requires the generic.xaml file to be loaded when the control is initialized. In WPF C# custom control library, the below code does that automatically,

C# Code

public class CustomControl1 : Control

{

static CustomControl1()

{

DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));

}

}

Or we can just have the DefaultStyleKey overridden in the constructor,

C# Code

public class CustomControl1 : Control

{

public CustomControl1()

{

this.DefaultStyleKey = typeof(CustomControl1);

}

}

F# Solution

BAML conversion doesn’t work in F# because the MSBuild targets project for F# has issues when building the generic.xaml as a “Page” element.

On further investigation, I found that we can manually do the steps through code and make the control apply the template defined in XAML. Below are the steps that needs to be done,

1. Override the “DefaultStyleKey” property,

do this.DefaultStyleKey <- typeof<WatermarkTextBox>

2. Load the resource file and merge it to the control’s resources collection,

let resourceDict = Application.LoadComponent(new Uri("/FSharp.SampleControls.Wpf;component/Themes/generic.xaml", System.UriKind.Relative)) :?> ResourceDictionary

do this.Resources.MergedDictionaries.Add(resourceDict)

This will ensure that the control template is implicitly set to the control, you also have the OnApplyTemplate() getting called when you override that method. That’s it; we have loaded the control template and enabled the custom control to load like a normal WPF component. I also tested by editing the control’s Style using Blend and that also worked,

clip_image002

The full test sample is available in this link. The project contains a simple implementation of a WatermarkTextBox as a WPF custom control; it also has a C# WPF application that uses it.

I have also prepared a simple F# WPF custom control library project, You can download that from this link. You have to place this in the “Project Templates” location,

Windows 7

C:\Users\{UserName}\Documents\Visual Studio 2010\Templates\ProjectTemplates

This should enable VS2010 to load the template.

F# “fun” with Windows Phone 7

 

Don syme announced the availability of F# for Windows Phone 7 (link). Daniel Mohl has a project template for F# apps that Don showed in the F# community demo (link).

Note: Anyone wanting to start off a project from scratch can download the project template that I created from here. This is a simple F# WP7 app template without the extra demo files.

As with my previous posts (long back, can’t find enough time these days), I ported the Stock ticker code base to WP7. The UI is pretty simple, It only has a ListBox to show the stock data. The ListBox has a custom ItemTemplate that defines the layout for the input data pulled over the web (Yahoo finance). The application also checks for network connectivity. Below is a snapshot,

image

This sample only pulls the stocks when you click the button, Since it is used in a phone, actual CEP kind of scenario would not be suitable, so keeping the updates in deferred mode. UI polishing + added features would make this a good app for the market store, what do you think? 😉

Sample with source code link.

-Fahad

CEP Client – Remix (WPF & SL)

My previous post had implementation of Rx + F# + Syncfusion WPF GridDataControl. This post is a continuation with a cleaner sample + a Silverlight 4 client using the same abstractions. The technologies used are,

· Rx (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx), Download the latest version for Silverlight.

· F# – (http://www.silverlight.net/getstarted/silverlight-4/) Get the latest SL4 tools for VS2010, it includes a copy of Fsharp.Core.dll built for the SL 4 Framework.

The sample code is much the same; it uses code sharing between the WPF / SL source projects with some conditional compilation constants to make it build properly. One more caveat is that, since we doing a Webrequest call over the network, we need elevated permissions to do in a Silverlight application, without this we would have to host a client access policy file in the server. Only way is to run the SL application in an elevated trust.

Silverlight 4 – Out Of Browser application,

image

You would have to send me an email again to get the sample code. May be if I get more time, I can work on this and make it colorful to host it in our site itself :).

-Fahad

‘case like classes’ in C# 4.0

 

“case classes” are a notion in scala. It provides an easier syntax to quickly create POJO objects (Its POCO – Plain Old CLR Objects, in .NET). When I first looked at this couple of days back, I was sure this could done with C# too. Here is what I checked,

  • Use dynamic keyword from C# 4.0
  • Create a simple key/value pair to define the property bag values.
  • Construct a dynamic object based on these values.

This looks pretty straight forward. The code is very simple, the CaseClass <- (dervies from) DynamicObject, and keeps a simple key/value pair mapping.

public class CaseClass : DynamicObject
    {
        private Dictionary<string, object> members;
        public CaseClass(IDictionary<string, object> propertyValues)
        {
            this.members = new Dictionary<string, object>();
            foreach (var kvp in propertyValues)
            {
                if (!this.members.ContainsKey(kvp.Key))
                {
                    this.members.Add(kvp.Key, kvp.Value);
                }
            }
        }

        public CaseClass Extends(CaseClass parent)
        {
            var instance = new CaseClass(this.members);
            foreach (var kvp in parent.members)
            {
                if (!instance.members.ContainsKey(kvp.Key))
                {
                    instance.members.Add(kvp.Key, kvp.Value);
                }
                else
                {
                    throw new InvalidOperationException("child object contains the same property key " + kvp.Key);
                }
            }

            return instance;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (this.members.ContainsKey(binder.Name))
            {
                result = this.members[binder.Name];
                return true;
            }
            else
            {
                return base.TryGetMember(binder, out result);
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!this.members.ContainsKey(binder.Name))
            {
                this.members.Add(binder.Name, value);
            }
            else
            {
                this.members[binder.Name] = value;
            }
            return true;
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return this.members.Keys;
        }
    }

Couple of interesting things,
  • It uses the fluent API interface.
  • If you want to extend a class object, simply call the Extends method and pass the parent class to it.

Usage of it is pretty simple too,

class Program
   {
       static void Main(string[] args)
       {
           var dict = new Dictionary<string, object>() { { "Name", "Fahad" }, { "Age", 25 } };
           var personalInfo = new CaseClass(dict);
           dynamic d1 = personalInfo;
           Console.WriteLine(d1.Name);
           Console.WriteLine(d1.Age);

           var work = new CaseClass(new Dictionary<string, object>() { { "Profession", "Software Engineer" } });           
           dynamic d2 = work.Extends(personalInfo);
           Console.WriteLine(d2.Profession);

           Console.ReadKey(true);
       }
   }

This shows the power of C#, (of course you don’t get intelli-sense / static typed values), but then its only for specific use cases, not everyone has to deal being dynamic. There are couple of more features that the Scala case classes provide, the ToString() / GetHashCode() / Equals() overrides that the scala compiler does for you. Anybody interested can simply add some more functionality in the above code.

Disclaimer: This post is just to show the usage of C# in one way as in Scala, It doesn’t completely replicate the functionality that is provided as-is in Scala.

-Fahad

CEP client with WPF Grid Data Control

CEP Client with WPF GridDataControl

Microsoft StreamInsight CEP platform is very powerful to develop Complex Event Processing (CEP) systems. There are several development models that we can follow. In this post we will use the IObservable / IObserver model using .NET Reactive extensions (Rx). Since this would be a real-time application, we would also be using F# async workflows to pull stock data.

image

F# async workflows are the coolest part of using F# in a real-time application. It allows writing concise code that

· Executes in parallel

· Expose to another .NET library with ease

I won’t go in detail about F# except for the async workflow used in this application. There is a three part series on using design patterns for F# async workflows, I have used the Pattern #3 in this post, since we are using Rx to invoke the workflows. In this design pattern, the worker reports the progress through events, modified version of AsyncWorker<> code is shown below,

type JobCompletedEventArgs<‘T>(job:int, result:’T) =

inherit EventArgs()

member x.Job with get() = job

member x.Result with get() = result

type AsyncWorker<‘T>(jobs: seq<Async<‘T>>) =

// This declares an F# event that we can raise

let allCompleted = new Event<‘T[]>()

let error = new Event<System.Exception>()

let canceled = new Event<System.OperationCanceledException>()

let jobCompleted = new Event<JobCompletedEventArgs<‘T>>()

let cancellationCapability = new CancellationTokenSource()

/// Start an instance of the work

member x.Start() =

// Capture the synchronization context to allow us to raise events back on the GUI thread

let syncContext = SynchronizationContext.CaptureCurrent()

// Mark up the jobs with numbers

let jobs = jobs |> Seq.mapi (fun i job -> (job, i+1))

let raiseEventOnGuiThread(evt, args) = syncContext.RaiseEvent evt args

let work =

Async.Parallel

[ for (job,jobNumber) in jobs ->

async { let! result = job

syncContext.RaiseEvent jobCompleted (new JobCompletedEventArgs<‘T>(jobNumber, result))

return result } ]

Async.StartWithContinuations

( work,

(fun res -> raiseEventOnGuiThread(allCompleted, res)),

(fun exn -> raiseEventOnGuiThread(error, exn)),

(fun exn -> raiseEventOnGuiThread(canceled, exn)),

cancellationCapability.Token)

/// Raised when a particular job completes

[<CLIEvent>]

member x.JobCompleted = jobCompleted.Publish

/// Raised when all jobs complete

[<CLIEvent>]

member x.AllCompleted = allCompleted.Publish

/// Raised when the composition is cancelled successfully

[<CLIEvent>]

member x.Canceled = canceled.Publish

/// Raised when the composition exhibits an error

[<CLIEvent>]

member x.Error = error.Publish

We have used [<CLIEvent>] attributes to mark these events for exposing to other .NET CLI languages. Since we are using Rx we need to have an event that inherits from System.EventArgs, JobCompletedEventArgs<T> does that here. The AsyncWorker is now ready to be used as a library for running parallel code.

Stock Quotes Reader

The Stock Quotes Reader defines a wrapper that does a request to the server (it would be yahoo finance here) and pull the stocks.

type StockAvailableEventArgs(stocks:string[]) =

inherit EventArgs()

member x.Stocks with get() = stocks

type StockQuotesReader(quotes:string) =

/// event raised for every job completed, this is easier to use in other CLI languages

let stockAvailableEvent = new Event<StockAvailableEventArgs>()

let httpLines (uri:string) =

async { let request = WebRequest.Create uri

use! response = request.AsyncGetResponse()

use stream = response.GetResponseStream()

use reader = new StreamReader(stream)

let lines = [ while not reader.EndOfStream do yield reader.ReadLine() ]

return lines }

// n – name, s – symbol, x – Stock Exchange, l1 – Last Trade, p2 – change in percent, h – high, l – low, o – open, p – previous close, v – volume

let yahooUri (quotes:string) =

let uri = String.Format("http://finance.yahoo.com/d/quotes.csv?s={0}&f=nsxl1hlopv", quotes)

uri

member x.GetStocks() =

let stocks = [httpLines(yahooUri quotes)]

stocks

member x.PullStocks() =

let stocks = x.GetStocks()

let worker = new AsyncWorker<_>(stocks)

worker.JobCompleted.Add(fun args ->

stockAvailableEvent.Trigger(new StockAvailableEventArgs(args.Result |> List.toArray))

)

worker.Start()

static member GetAsyncReader(quotes) =

let reader = new StockQuotesReader(quotes)

let stocks = reader.GetStocks()

let worker = new AsyncWorker<_>(stocks)

worker

[<CLIEvent>]

member x.StockAvailable = stockAvailableEvent.Publish

The above wrapper class does some interesting things,

· It has a async block code that yield returns a line of data based on the response stream.

· PullStocks will create async requests and raise the StockAvailable event whenever the async job is completed.

CEP Client

On the CEP client we would be using the below things,

· Syncfusion WPF GridDataControl – it works well with high speed data changes, keeping minimal CPU usage.

· Rx to create requests and update the ViewModel bound to the Grid.

Setup the application

The WPF application uses simple MV-VM by defining a StocksViewModel to hold stock data. The Stocks collection is bound to the Syncfusion WPF GridDataControl.

<syncfusion:GridDataControl Grid.Row="0" x:Name="grid"

NotifyPropertyChanges="True"

AutoPopulateRelations="False"

Width="Auto"

AllowGroup="True" ShowGroupDropArea="True"

AutoFocusCurrentItem="False"

ItemsSource="{Binding Model.Stocks}"

AllowEdit="False"

IsGroupsExpanded="True"

ShowAddNewRow="False">

</syncfusion:GridDataControl>

Using Rx to create requests

This real-time application requires real-time data that will be pulled over the wire for every 500 milliseconds. We would be making use of the IObservable to create a streaming request and repeat that over a time delay,

var stockReader = new StockQuotesReader(“MSFT+GOOG+INTL”);

var stockFeeds = Observable.Defer(() =>

{

stockReader.PullStocks();

var evt = from e in Observable.FromEvent<StockAvailableEventArgs>(stockReader, "StockAvailable")

select new { Stocks = e.EventArgs.Stocks.ToStockQuotes() };

var delayedEvt = Observable.Return(evt).Delay(TimeSpan.FromMilliseconds(delay));

return delayedEvt;

}).Repeat();

We now have a streaming real-time stock data pulled asynchronously over the web and shown on the Syncfusion GridDataControl.

clip_image004

If you want to get hold of the sample, send me a request.

Enabling Blend (/ VS designer) to identify ItemContainerStyle for custom control in Silverlight 3.0

When designing custom controls we would want the users to customize the appearance of the items that is added up in some derived form of ItemsControl. Say we have a property “ItemContainerStyle”, we would want that to be customized in Blend as it does for ListBox,

img

Lets say, we have a property called “MyButtonStyle”. To enable this property to be recognized by the designer, we would have to implement the StyleTypedPropertyAttribute in the implemented class,

[StyleTypedProperty(Property = "MyButtonStyle", StyleTargetType = typeof(MyButton))]
public class MyButtonItems: ItemsControl

That’s it. Hope this helps.

-Fahad

Being Very “Dynamic” – C# 4.0 – I

The world of .NET programming is heading towards a new direction, lots of frameworks, languages, services etc., to choose from. With all the rapid development, C# is also heading towards a new future, being to match the inter-op (or rather co-exist) with its Dynamic siblings (IronPython / IronRuby), it is rather fascinating to bridge the gap between two worlds, where the latter evolved from the previous one.

image

With C# 4.0, we have a new keyword “dynamic”, which offers the following features,

  • Binding with DLR
  • COM – Interop made easy
  • Conversions – between dynamic objects and other types are easy.

There may be scenarios, where constructing a dynamic object is absolutely necessary, Say, if we need to write some object reading from XML or some ATOM feed, we would normally parse the data to some predefined set (a static class). All is good in the world of static typing, and areas where you know exactly how your data (or Business object) would be. For dynamic scenarios, We have dynamic meta-data driven based programming, For instance, we could implement ITypedList, ICustomTypeDescriptor, or any derived version of PropertyDescriptor or any custom interface that defines the logic behind driving the meta-data.

The dynamic introduces a DynamicObject class that acts as an interface between the object store and the interaction between the CLR. You would simply have to inherit from the DynamicObject class and implement methods that would be used on the dynamic instance.

We will check out one simple sample that extends DynamicObject to have an object store,

public class MyDynamicObject : DynamicObject
{
private Dictionary<string, object> members;
public MyDynamicObject()
{
this.members = new Dictionary<string, object>();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (this.members.ContainsKey(binder.Name))
{
result = this.members[binder.Name];
return true;
}
else
{
return base.TryGetMember(binder, out result);
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!this.members.ContainsKey(binder.Name))
{
this.members.Add(binder.Name, value);
}
else
{
this.members[binder.Name] = value;
}
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this.members.Keys;
}
}

To use this we declare a dynamic instance,

dynamic d = new MyDynamicObject();
d.Name = “Hello World”;
Console.WriteLine(“Name : {0}”,d.Name);

With some help from the “reflector”, I was able to get an idea on how the dynamic objects were getting constructed in memory. And, thus came up an idea to write down a helper class that would automatically generate “CallSites” for Get/Set property,

public static class DynamicHelper

{
public static object GetValue(object dyn, string propName)
{
// Warning: this is rather expensive, and should be cached in a real app
var binder = Binder.GetMember(CSharpBinderFlags.None, propName,
dyn.GetType(),
new List<CSharpArgumentInfo> {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
});
var getterSite = CallSite<Func<CallSite, object, object>>.Create(binder);
return getterSite.Target(getterSite, dyn);
}

public static void SetValue(object dyn, string propName, object value)
{
var binder = Binder.SetMember(CSharpBinderFlags.None, propName, dyn.GetType(), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.LiteralConstant | CSharpArgumentInfoFlags.UseCompileTimeType, null) });
var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
setterSite.Target.Invoke(setterSite, dyn, value);
}
}

Keeping my fingers crossed, we should probably get the dynamic keyword support for WPF GridDataControl (hopefully with Silverlight too).

Sample codes for the post can be downloaded here.

– Fahad

Tagged

Embedding LINQ Expression for a method call

Consider evaluating an Expression at runtime, for some lame reason you had to call ToLower() on a string object, and create a predicate out of it. Using LINQ expressions simplifies the task of doing these things. Simply embed the custom Expression that would evaluate against the LINQ extension methods. Below is a sample MethodCallExpression to embed a ToLower() method inside a LINQ query,

private static MethodCallExpression GetToLowerMethodCallExpression(Expression memExp)
{
    var tolowerMethod = typeof(string).GetMethods().Where(m => m.Name == "ToLower").FirstOrDefault();
    var toLowerMethodCall = Expression.Call(
        memExp,
        tolowerMethod,
        new Expression[0]);
    return toLowerMethodCall;
}

Lets take a simple scenario, we would write a custom Expression (e) => some lambda functor, that would evaluate against a Contains predicate. We first would right down a normal functor that would return the value of a property by using a PropertyDescriptor,

Func<string, object> recordFunc = (columnName) =>
{
    var pd = properties.Find(columnName, false);
    return pd.GetValue(person1);
};

Since we cannot embed a full method inside an expression we split that into a Functor lambda, and then use that as a single expression given below,

Expression<Func<Person, bool>> e = (p) => p.Age1 == (int)recordFunc("Age2");

C# compiler generates a sequence of Expression calls to the lambda recordFunc (take a look in reflector with the compiled exe),

       Expression<Func<Person, bool>> e = Expression.Lambda<Func<Person, bool>>(Expression.Equal(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(Person), "p"), (MethodInfo) methodof(Person.get_Age1)), Expression.Convert(Expression.Invoke(Expression.Constant(recordFunc), new Expression[] { Expression.Constant("Age2", typeof(string)) }), typeof(int))), new ParameterExpression[] { CS$0$0000 });

If we split this above expression into more meaningful method call, it should be as below,

public static LambdaExpression Contains(this object source, string propertyName, string propertyName2, Expression<Func<string, object>> recordFunctor)
{
    var type = source.GetType();
    var paramExp = Expression.Parameter(type, type.Name);
    var member = Expression.PropertyOrField(paramExp, propertyName);
    var member2 = Expression.PropertyOrField(paramExp, propertyName2);
    var convertedExp = Expression.Convert(Expression.Invoke(Expression.Constant(recordFunctor), new Expression[] { Expression.Constant(propertyName2, typeof(string)) }), member.Type);
    var binaryExp = Expression.Equal(member, convertedExp);
    var lambda = Expression.Lambda(binaryExp, paramExp);
    return lambda;
}

We can then use the above Contains extension method to embed a normal expression into LINQ predicate syntax or any LINQ extension method that requires a BinaryExpression to execute.

Download the sample here.

-Fahad

Loading XAML from C# – HACK!!!!

Ever wondered how to convert XAML to C# or to load a huge XAML content from C#, this post will possibly give you the best workaround to load it :).

If you have large Brush values or large XAML content that you would want to instantiate and apply it dynamically thru C#, it is either you convert to string and use the XAML reader or convert everything to some equivalent C# code. One other way is you could put up the XAML content inside a resource dictionary and hook it into the generic.xaml file. For more info on generic.xaml you can check out creating control templates for WPF, which allows overriding templates through resource files.

Once you have the resource dictionary setup with the XAML content, Say as below,

<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DrawingBrush x:Key="Asterisk">
        <DrawingBrush.Drawing>
            <DrawingGroup>
                <DrawingGroup.Children>
                    <GeometryDrawing Brush="#FF000000" Geometry="F1 M 416.193,288.721L 406.118,
300.568L 406.212,300.848L 421.043,297.863L 421.043,307.284L 406.118,304.673L 406.025,304.952L 
416.193,316.426L 407.891,321.277L 402.574,306.818L 402.387,306.911L 396.977,321.277L 388.954,316.426L 
398.936,304.766L 398.936,304.579L 384.29,307.284L 384.29,297.863L 398.749,300.755L 398.842,
300.568L 388.954,288.814L 397.257,284.057L 402.48,298.329L 402.667,298.329L 407.984,284.057L 416.193,
288.721 Z "/>
                </DrawingGroup.Children>
            </DrawingGroup>
        </DrawingBrush.Drawing>
    </DrawingBrush>
</ResourceDictionary>

The above is a Asterisk symbol drawn with brush values. You could then create a WPF control instance and use the brush value as a background. Lets do that for a Border control,

private static ResourceDictionary GetResourceDictionary()
{
    ResourceDictionary rd = new ResourceDictionary();
    rd.Source = GetXamlConvertedValue<Uri>("Window1;component/Themes/Generic.xaml");
    return rd;
}

The above code simply creates a new Resource dictionary with the specified URI path. The GetXamlConvertedValue is simply a utility function that converts the string into the appropriate instance using TypeConverter,

public static T GetXamlConvertedValue<T>(string value)
{
    var converter = TypeDescriptor.GetConverter(typeof(T));
    if (converter != null)
    {
        return (T)converter.ConvertFromInvariantString(value);
    }
    return default(T);
}

 

Now we get the ResourceDictionary and get the DrawingBrush using the key “Asterisk”,

public static Brush BackgroundBrush
{
    get
    {
        var rd = GetCellRendererDictionary();
        var brush = rd["Asterisk"] as Brush;
        return brush;
    }
}

 

That’s it, We can simply get the value and set it as a background to the Border control. Like so any other content can be placed inside the ResourceDictionary and access it thru the Key/Value pair.

 

-Fahad

Dynamic LINQ Expressions – I

Generating dynamic LINQ expressions needs a bit of understanding on the IQueryable interface. Check out Matt’s series of posts on implementing the IQueryable interface –> LINQ Links. The strong drive for this post is that everything is strongly typed, of course we have the Dynamic LINQ library that comes in MSDN sample, but that comes with an over head of generating strings to perform operations. In many cases, strongly typed usage will result in controlling the flow more accurately.

Lets take a look at the extensions library that will be used for generating Expressions on a dynamic data source ( that implements IQueryable / IEnumerable ). In this post, we will look at generating OrderBy() query with different parameters defined in the Queryable class. Normally, there are helper classes that has implementation for generating LINQ expressions for IEnumerable and IQueryable interfaces. The Queryable class defines a wrapper thru which we can make calls to the IQueryProvider implemented for that source type (IQuerable / IEnumerable).

With our implementation,

  • We would go with making our objects AsQueryable().
  • Call the appropriate method from the Queryable class that defines the method.

OrderBy() query –

The OrderBy query generates a simple sort comparer with the property name that is present on the underlying IQueryable source,

/// <summary>
/// IQueryable expression for sorting in ascending.
/// </summary>
/// <param name="source"></param>
/// <param name="propertyName"></param>
public static IQueryable OrderBy(this IQueryable source, string propertyName)
{
    var sourceType = source.GetObjectType();
    ParameterExpression paramExpression = Expression.Parameter(sourceType, sourceType.Name);
    MemberExpression memExp = Expression.PropertyOrField(paramExpression, propertyName);
    LambdaExpression lambda = Expression.Lambda(memExp, paramExpression);
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable),
            "OrderBy",
            new Type[] { source.ElementType, lambda.Body.Type },
            source.Expression,
            lambda));
}

Taking a closer look at the functions,

Expression.Parameter – Defines the parameter on which the object is referred. Normally we would assign some parameter for the source in our LINQ expressions, Say for Northwind Orders table,

var orders = Orders.OrderBy( order => order.ShipCountry );

Like so, we can dynamically generate the above expression as,

var ordersQuerable = orders.AsQueryable();

var sortedOrders = ordersQueryable.OrderBy(“ShipCountry”);

You may want to perform multi-sorting on the underlying IEnumerable type, the other OrderBy related functions that have similar implementation are,

  • OrderByDescending
  • ThenBy
  • ThenByDescending

For building a big expression dynamically, all you have to do is loop thru the collection of sorted columns, and recursively build the expression by calling the OrderBy / OrderByDescending / ThenBy / ThenByDescending in some logical sequence.

Note: OrderByDescending / ThenByDescending will be generated only for IOrderedQueryable instance, So you need to maintain some kind of an instance that holds IOrderedQueryable from the return set of OrderBy / ThenBy.

Helper method:

This gets the underlying object type for the IQueryable source.

private static Type GetObjectType(this IQueryable source)
{
    var enumerable = source.GetEnumerator();
    var hasItem = enumerable.MoveNext();
    if (hasItem)
    {
        return enumerable.Current.GetType();
    }
    return null;
}

In the next posts, we will check out generating WHERE expression dynamically.

Hope this helps.

– Fahad