Tuesday, October 15, 2013

SignalR - Part 3 - Hello, Client

If you’re just joining us, we’re in the process of creating a messaging app with SignalR. Over the next series of posts we want to be able to allow users to message to different groups, create a UI that will highlight new messages, and even store those in a database.

But we’re walking before we run, and right now we’re just implementing a “Send All” functionality. You submit a message and we’re going to send it to everyone connected.

In our previous post, Hello, Server, we examined the server side of our little app. Now it’s time to turn our attention to the client. We’re using MVC, so I’m going to need a controller and a view.

We started with a blank MVC project[1] in VS Web Express[2]. I’m going to add on a simple HomeController and have it return the basic Index view.[4]

public class HomeController : Controller

{

   public ActionResult Index()

   {

         return View();

   }

}

I’m going to create the view. I’m going to empty it out and add in an unordered list, a textbox and a button[4].

<ul id="messages">

 

</ul>

 

Message:

<input type="text" id="new-message" value="" />

<button type="button" id="send-message">Send!</button>

To make life easier, I’m adding in the jQueryUI NuGet package. jQueryUI will include jQuery and make it easier to grab my items and add on the cool effects I’m going to want. Just do a search for jQueryUI and grab the first package. And drag and drop out the CSS and scripts mentioned below.

image_thumb[1]

<link href="~/Content/themes/base/minified/jquery-ui.min.css"

                     rel="stylesheet" />

<script src="~/Scripts/jquery-1.6.4.min.js"></script>

<script src="~/Scripts/jquery-ui-1.10.3.min.js"></script>

For SignalR we need two scripts. The first is the generic SignalR script file. The second is the dynamic SignalR script that will contain all of our methods from our hub. That’s the script file that’s mentioned at the bottom of the readme.txt file. Don’t forget that reference or you’ll wind up getting null and unknown errors. Yes, I speak from experience.

<script src="~/Scripts/jquery.signalR-1.1.3.min.js"></script>

<script src="~/signalr/hubs"></script>

Now on to the code. We need to do two things. First, we need to create the function in JavaScript for the server to call. If you remember from our previous post we called it UpdateMessages and it took a single string parameter. Second, we need to call the method on the server.

First up, creating the method the client can call.

<script>

   $(function() {

      var hub = $.connection.messageHub;

 

      // Create the method on the client

      // that can be called from the server

      hub.client.updateMessages = function (message) {

         var item = "<li>" + message + "</li>";

         $("#messages").append(item);

      };

 

      // more code to come

   });

</script>

The first line of code is the jQuery shortcut for document.ready. That will execute once everything on the page is loaded. The second line is where we get into SignalR. The connection object will give us access to the SignalR connection. Off that object we can access our hub using the exact same name we called it when we created the class, with camel casing.

The next block is where we register the function. You’ll notice we use the client property, which gives us access to the client side of the hub, which is what we use to register the method. You’ll also see we named our method updateMessages using the JavaScript convention of camel casing. This goes back to one of the little things that SignalR does for us – it automatically handles casing. We can code using the casing convention of the environment we’re in.

The signature for the function is exactly what is on the method in our hub – one parameter. The name doesn’t matter, but I like consistency. So we’ll call it message. From there it’s just normal jQuery. Grab the text, put <li> tags around it, and append it to our list of messages.

And that’s the big thing I again want to highlight. We’re free to focus in on what we need to implement on the client, not what needs to be done just to send messages back and forth. We only have two lines of code above that are SignalR focused. The rest is our real implementation.

Now let’s send a message up to the client.

// Wait for the connection to be made

$.connection.hub.start().done(function() {

 

   // Create a click event handler to send the message

   $("#send-message").click(function () {

      var message = $("#new-message").val();

      hub.server.sendNewMessage(message);

      $("#new-message").val("");

   });

});

The above code was placed where I had the “more code to come” comment.

Let’s break this down. The first thing we’re doing is making sure the connection to the server has been made. We don’t want someone clicking on the button and getting an error just because we haven’t connected to the server yet.

The next line is again using jQuery, this time registering the click event and then grabbing the value from the textbox.

Finally, we’re back to SignalR. You’ll notice we’re calling the server property of the hub and accessing the sendMessage function. I know I’m sounding like a broken record[5], but we only have two lines of SignalR code. The rest is jQuery. The rest is just our implementation.

Now we’re ready to test! Ctl-F5 to launch it and we get our basic textbox. We type in a message, hit submit, and we see our new message in the list.

image

And that’s it! We now have our Hello World SignalR application, from client to server.

There’s still more work to be done.

But for right now, let’s just enjoy the fact that with just a bit of client and server code we have a pretty slick little application.

Source code:

---------

[1] I like the templates that are built in. But right now I just want to keep things simple.
[2] I’m using that simply because that’s what installed on my Surface. Plus, it’s a nice way to show I’m not using anything special.
[3] I’m using the HomeController and the Index action simply because it’s the default route. This isn’t an MVC blog post. :-)
[4] Yes, I’m not putting in any html or other tags. Again, I’m trying to keep this as clean as possible.
[5] Or a scratched CD if you don’t remember records. I have no MP3 equivalency.

Monday, October 14, 2013

SignalR - Part 2 - Hello, Server

In my previous blog post, I discussed the concepts of SignalR and why you should be interested as a developer. Hopefully I sold you. But if I didn’t, I think getting in and writing some code will help.

Here’s the basic scenario, and sort of our “SignalR 101” demo. I want a simple chat application for a site. I want to create a form and allow someone to broadcast a message to everyone else connected to the page.

In addition, I’d like to store that information in a database so people can see the most recent 10 messages. And, while we’re at it, I’d like to make sure the UI highlights new messages.

But let’s walk before we run. Let’s start by broadcasting messages to all connected users. And right now I just want to get the server side (or hub) set up and ready to go.

First step – get SignalR. SignalR is available as a NuGet package. So just fire up the NuGet manager and search for SignalR. You’ll just need the first package.

image

The result is one of the main reasons to use NuGet. First, you’ll notice it grabs all the prerequisites for us. Second, it opens a text file with the next steps.

The first step that’s called out is to add a line of code to our global.asax file. This little line will find all of our SignalR hubs and make them available. That one little line will also generate a dynamic bit of JavaScript for us that contains the JavaScript methods for the client to use. The readme.txt file calls out the reference that needs to be made to that dynamic file.

Long story short, we need to do what the readme.txt file says. Since we’re just focused on the server side right now, we’re just going to make our global.asax file look like this:

protected void Application_Start()

{

   // Register the default hubs route: ~/signalr

   RouteTable.Routes.MapHubs();

   // normal code below

}

And that’s it. That’s the server configuration part. That’s everything that needs to be done for the automatic step down that I talked about in the previous blog post. And we can turn our attention to making our actual implementation.

Let’s create our hub first. You can see it listed below.

using Microsoft.AspNet.SignalR;

using System;

 

namespace SignalRBlog.Hubs

{

   public class MessageHub : Hub

   {

      public void SendNewMessage(String message)

      {

         Clients.All.UpdateMessages(message);

      }

   }

}

Take a look at it. Notice if there’s anything special. I’ll give you a hint – there really isn’t. Well, one thing. But on the whole there isn’t.

And that’s the beauty of SignalR. I create the code I need to create, focus on the features I need to implement, and let SignalR take care of the details.

Let’s break things down. First you’ll notice the inheritance. The Hub class is inside the Microsoft.AspNet.SignalR namespace and is the base for all hubs. That is what the register method will focus in on when registering our hubs, and it’s what makes the Clients object (and a few others) available.

Second, you’ll notice the basic SendNewMessage method. Nothing fancy there. Just a public method, taking a String parameter, and returning void. Programming 101.

And finally we get to the real SignalR code – the Clients object. The Clients object gives us access to everyone that’s currently connected. As we’ll see in later blog posts we can use that object to target certain sets of users. But for right now we want to broadcast our message to everyone. The property of Clients that will give us all users is imaginatively named All.

All is a dynamic object. It does represent all users and allows me to call a method on all users. But it’s a dynamic object. Here’s the thing – SignalR doesn’t know what methods we may want to call or what it is we’re going to want to be able to do. As a result it uses a dynamic object which allows us to add on the methods we’re going to need on the fly. At a later point we’ll have to register that method on the client, but that’s the next blog post.

So, here’s what we’ve got. We’ve added SignalR to our project. We’ve added the call to our global.asax file to register the dynamic JavaScript that’s needed. And we created our hub with our first method that can be called from the client. What’s next? Well, to create the client! And that’s the next blog post.

Thursday, October 10, 2013

SignalR - Part 1 - The Introduction

Recently I had the pleasure of presenting the MVC 4 Jump Start with Jon Galloway. It was an awesome experience, we covered a lot of great content, and every demo worked... Until the very end.

Now, as a quick side note, I must say I was impressed that everything worked up until that point. We were doing all of the demos live, and coding without a safety net with over 3,000 people watching was a real rush. And to only have one demo go sideways? I’ll certainly take that. And I was able to get it fixed before we went off the air.

But I’d like to try to take a bit of time and go back through the demo and discuss how SignalR works and what it can do for you. There’s a fair amount of ground that I’d like to cover, and I’m going to break this into smaller, bite-sized chunks so you can skip to the section(s) that interest you most.

Let’s get started with the problem statement and how SignalR, behind the scenes, simplifies the development process.

One thing we as web developers have long wanted to do is be able to send messages down to the client browser. As applications have become more robust and closer to replacing full-blown desktop applications the need for two-way communications has become even greater. But, unfortunately, the options that we’ve had available to us have been a bit of a mixed bag.

The first option that we have is to use polling. Create a block of JavaScript that has a delay timer to ping the server and ask if there are any new messages. This is the programming equivalent of the 4-year old in the back of the car asking, “are we there yet? are we there yet? are we there yet?” Not ideal.

Another possible option is to create an invisible iframe to use a chunked block, sometimes known as a forever frame. This will allow the server to periodically send down JavaScript to the client, which the client will then execute. Again, not ideal.

If we’re looking for true server to client communication we have Server-Sent Events. Originally added to Opera, Server-Sent Events has been made part of the HTML5 specification. It uses HTTP and allows the server to send messages to the client. However, while most other browsers support Server-Sent Events, Internet Explorer does not. So, again, not ideal.

And finally we have WebSockets. While WebSockets uses port 80 and 443, it is a separate protocol from HTTP. It allows for two-way communication in a similar fashion to a network socket that you may have used in the past. The problem with WebSockets is while they’re supported by most modern browsers, older browsers don’t have support. Plus, programming WebSockets is similar to doing socket programming, which isn’t really my favorite style.

So, here’s what we’ve got – four possible solutions for two way communication. We’d like to use WebSockets, but we can’t guarantee the browser will work with them. Failing that, we’d like to use Server-Sent Events, then forever frames, and finally polling. But, I’ve got better things to do with my time than to not only figure out which the browser supports but to create the required code implementations.

While we’re at it, even if I was guaranteed the ability to use WebSockets, I don’t much enjoy programming against them.

With WebSockets I have essentially one method that I can call to send a signal to the server, and one method that I can call to send a signal to the client. It’s up to me on each side to determine the type of message that’s been sent, and to handle the serialization to and from JSON or text. If there’s two different messages I need to be able to send to the client, maybe a “NewComment” and “EditedComment” signal, I need to add the logic to detect the message type, and then act upon the payload that was sent with the rest of the message.

This is where the beauty of SignalR is revealed.

For starters, SignalR will handle the step-back in messaging types automatically for me. It’ll try WebSockets, and then fail back to Server-Sent Events, and then forever frames, and then, if it must, long polling. This way I don’t need to figure out which the browser supports and, more importantly, include the code for each of the methodologies. SignalR does it for me.

Secondly, and I think this is the coolest part, SignalR allows me to create methods on the client that are callable from the server, and, in turn, methods on the server that are callable from the client. Essentially, on each side, I just create normal methods and then call them from the opposite side. So, in my scenario of “NewComment” and “EditedComment” I’d just implement two JavaScript methods named newComment and editedComment, and on the server call those as if they were local to the server. SignalR will handle the communication (and differences in casing) automatically for me.

Or, to put it even more simply, SignalR makes it very easy for me to implement that two way client-server communication we as developers have been craving for years. I don’t need to focus dirty work that needs to be done behind the scenes, I just focus on the implementation and what I’m trying to accomplish.

There’s how SignalR works behind the scenes and what it’s going to do for us. Next up? Let’s get the server side up and running!

Wednesday, December 12, 2012

Everything is a List

If you take one of my SharePoint classes, there’s a couple of things that are guaranteed. You’re going to hear corny jokes. You’re going to hear obscure references to 80s movies and pop culture. And you’re going to hear me say the following phrase ad nauseum: “Everything in SharePoint is a list, and everything in a list is a list item.”

While this is a slight oversimplification, there’s a method to my madness.

SharePoint is a very large, very flexible, very configurable product. There is no “one size fits all” implementation of SharePoint. As a result, whenever I teach SharePoint my goal is to talk about the technologies, talk about what each item does, and try to arm my students with the knowledge needed to go back to their desks on Monday morning to make decisions that are right for their environment. And that phrase is one of the biggest tools in my tool belt. That phrase answers many, many questions.

Consider the blog site.

When you create a SharePoint blog site, SharePoint creates a few lists. In particular, the big three are Posts, Comments and Categories. Let’s touch on a few common questions about the blog site and see if the phrase “Everything in SharePoint is a list, and everything in a list is a list item” answers the question.

BlogSite

Q: How do I customize the categories for my blog posts?
A: Everything in SharePoint is a list, and everything in a list is a list item.

Your categories are stored in a list named, conveniently enough, Categories. If you wish to add, remove or otherwise customize the categories that are available simply navigate to the Categories list and modify the items.

Q: How do I control who’s allowed to create posts?
A: Everything in SharePoint is a list, and everything in a list is a list item.

All blog posts become items in the Posts list. If you wish to add or remove blog authors, change the permissions of the Posts list.

Q: How do I control what users are allowed to comment on blog posts?
A: Everything in SharePoint is a list, and everything in a list is a list item.

All comments are list items in the Comments list. To grant or revoke a user’s ability to create comments modify the permissions of the Comments list.

Q: Can I get an alert whenever a new blog post is added?
A: Everything in SharePoint is a list, and everything in a list is a list item.

Create an alert for yourself, or other users, on the Posts list.

Q: Can I enable approval of comments?
A: Everything in SharePoint is a list, and everything in a list is a list item.

To enable approval of comments, open the List Settings page, choose Versioning Settings, and then choose “Yes” for “Require content approval for submitted items?”.

Q: Can I create a workflow for comment approval?
A: Everything in SharePoint is a list, and everything in a list is a list item.

Because comments are stored as items in a SharePoint list, you can create and bind whatever workflow you need to the Comments list.

Notice the common theme here[1]. Every question was answered by simply applying our knowledge of lists to each scenario. To meet the goals, the answers were to modify permissions, work with list items, and modify list options. Everything in SharePoint is a list, and everything in a list is a list item. Once you’ve got that, quite a bit of SharePoint falls into place.

[1] It’s sort of hard to miss. :-)

Friday, December 7, 2012

How do I Connect with Other MCPs?


I will always remember my first TechEd in 2004. It was in San Diego. I’d been an Microsoft Certified Trainer (MCT) at that point for about 5 years, but I’d been rather insulated from the outside world. I knew there was a community of MCTs out there, but I’d never met any of them outside of communication on the newsgroups[1]. I didn’t know what to expect. And then, upon showing up at the preconference day, I realized there was this whole new world of people I could connect with. That experience was one of the events in my life that I can point to that changed the direction of my career, and my life.

I settled into the preconference event for MCTs. Before I knew it I was inundated by people walking up to me, introducing themselves, and wanting to finally “put the face to the name”. I was also mesmerized by the interaction between the MCT there. This was not merely a normal gathering of peers. This was a reunion. These were people that truly enjoyed each others’ company and relished the opportunity to reconnect.

I didn’t quite know what was going on, but I knew I wanted in. So while internally I’m a bit of an introvert I pushed that to the side to throw myself right into the mix. Years later I’m still connected with most everyone there. And I’m extremely fortunate to call a fair number of them friends – and that’s not a word I use very lightly.

The MCT community is rather large and rather active. It may be one of my favorite things about being an MCT.
However, community isn’t the sole providence of MCTs. As a Microsoft Certified Professional (MCP) you’re a member of a community that numbers into the hundreds of thousands. Each year at TechEd, MMS, SharePoint Conference, SQL PASS, ..., hundreds of MCPs descend upon a convention center for a week of learning and fun. Every event features numerous opportunities to visit and connect with other attendees and MCPs.

You never know who it is you’re going to meet at events like that - at mixers, at social functions, etc. - or just in passing. Over the course of many conferences over the last several years I’ve met literally hundreds of people. I’ve met some of the most fascinating, interesting people through conferences. My life is much richer for having made those connections.

While I love meeting people on a personal level, on a professional level it’s critical. I’m an independent contractor. I need to work to find work. I need to market myself. The best way to do that is through in person, face to face contacts. These days all of my business is direct through training centers or other organizations. And it’s all because of people that I’ve met and come in contact with.  I’m always armed with a handful of business cards[2], a firm handshake, a warm smile and a quirky laugh. Those little things allow for quick connections, which leads to the next conversation, which leads to a business conversation, which leads to more work. As I type this I’m struggling to remember the last time I had to fill out an application or hand someone a resume.

Introducing yourself to someone you don’t know can certainly be intimidating if you’re a bit introverted. I know – as I mentioned before, despite my extroverted exterior, inside I’m a bit of an introvert myself. On my personal blog[3] I used to do a feature on Friday called my Friday Five. In that vain, here are 5 things that help me connect with people.

1.  Take a deep breath and remember they’re probably just as nervous as you. It’s true. Everyone has some level of nervousness when it comes to talking with strangers. They’re no different than you.

2.  Get the other person talking about themselves. Everyone loves talking about themselves. Everyone has an inner narcissist. Some of us[4] don’t hide it as well as others. Not only does that allow the person you’re trying to meet to do something they love to do, you’re likely to hear some amazing stories.

3.  Take up a hobby. Hobbies give you a common bond with someone even if you know nothing else about them. Personally, I’m a runner. So meeting another runner gives us an instant kinship. It can be almost anything – cooking, knitting, Settlers of Catan. And, if you’re looking to set up a “geek play date” if you will, a hobby gives you something you can do together.

4.  Compliment someone’s funny t-shirt. As someone with a pretty good collection of geek shirts, I can tell you the biggest reason I wear them is for the reaction. And it can be a great conversation starter.
     Other: Hey – great shirt! Where did you get that?
     Me: Thanks! It’s one of my favorites. I got it at Think Geek.
     Other: Really? That’s awesome! I love that site.
     Me: Me too! I always have to resist the urge to just buy one of everything there.

5.  Maintain “cultural literacy”. Know what’s going on in the world, both real news wise and pop culture wise. Depth isn’t important here, breadth is. Having a wide variety of subjects you can talk about, even at a very shallow level, can be very helpful in keeping a conversation flowing. For example, if you’ve never watched Breaking Bad[5], knowing the basic premise will allow you to talk with someone about the show.

Being a geek doesn’t have to be about living in a silo. There’s a whole community of geeks to connect with out there. And that community is one of my favorite parts of being an MCT and MCP. So next time you’re at a conference, stop by and introduce yourself. I’d love to meet you.

[1] Bring back, oh, nevermind… (Closed circuit joke)
[2] Trading cards, actually. They’re really cool. :-)
[3] When I used to maintain a personal blog
[4] For example, someone who would put together a blog at blog.geektrainer.com, for example
[5] One of the greatest shows on television, BTW

Thursday, May 10, 2012

Anonymous Methods, Lambdas and LINQ

… oh my!

[Editor's note: For whatever reason, the tool that I'm using to inject the code (with line numbers, which helps with the explanations) likes to mess with the formatting. I hope that the extra white space doesn't detract too much from the article. After typing all of this, really don't want to start debugging CSS issues. ;-)]

Lately, one of the most common questions I've received from students is, basically, "What in the world is this syntax and what does it mean?[1]"

dc.Categories.OrderBy(c => c.Name);

Well – it's a lambda statement. But of course if you haven't seen one, you need a bit more information than that.

Quite frequently, a full explanation would simply take too long or send the class down another path far away from the topic at hand. What I want to do with this post is answer that question fully.

I'm going to answer the question using one of my biggest philosophies when it comes to training, which is to explain it in the way that I understood it, in whatever method it was that made it finally click for me. In this case, that means stepping all the way back to the beginnings and showing essentially the progression that got us to where we are today.

That's going to take a little while here, so bear with me.

Trust me, we'll get there.

Let's take a simple class called Customer that's defined below.

public class Customer
{
    public Customer(String firstName, String lastName)
    {
        this.FirstName = firstName;
        this.LastName = LastName;
    }
    
    public String FirstName { get; set; }
    public String LastName { get; set; }
    
    public override String ToString()
    {
        return LastName + ", " + FirstName;
    }
}

Pretty straight forward. Couple of properties, a simple constructor. Looks good. Now let's create a couple, put them into a list, and display them.



   1: public static void Main()
   2: {
   3:     List<Customer> customers = new List<Customer>();
   4:     customers.Add(new Customer("Susan", "Ibach"));
   5:     customers.Add(new Customer("Christopher", "Harrison"));
   6:     customers.Add(new Customer("Dave", "Baxter"));
   7:     
   8:     foreach (Customer customer in customers) {
   9:         Console.WriteLine(customer);
  10:     }
  11: }

Again – pretty straight forward[2]. And the output will of course be exactly what we'd expect:


Ibach, Susan
Harrison, Christopher
Baxter, Dave


Now let's see if we can't sort those customers. Fortunately, List has a Sort method. Let's update line 7 to call sort (code below) and run it and see what happens.


customers.Sort(); // Line 7


Result:


Unhandled Exception: System.InvalidOperationException: Failed to compare two elements in the array. ---> System.ArgumentException: At least one object must implement IComparable.


Well that wasn't ideal… In a nutshell, what the runtime is trying to tell us is that we told it to sort a list of customers, but it has no idea how to sort our customers. Makes sense. How do we tell it to sort our customers? Well – by implementing IComparable.


IComparable is an interface with one method – CompareTo(object). CompareTo returns an integer based on the following criteria:


Current object (this) is less than the other object, return a negative number
Current object (this) is equal to the other object, return 0
Current object (this) is greater than the other object, return a positive number


One thing that you'll notice is that every primitive type (and strings) in .NET already implement IComparable. This means we can take advantage of their implementation. Let's update our Customer class to implement IComparable and sort by LastName[3].



   1: public class Customer : IComparable
   2: {
   3:     // existing code
   4:  
   5:     public int CompareTo(object obj)
   6:     {
   7:         // put all NULL objects at the top
   8:         if(obj == null) return 1;
   9:     
  10:         Customer otherCustomer = obj as Customer;
  11:         if(otherCustomer != null) // obj is a customer
  12:             return this.LastName.CompareTo(otherCustomer.LastName);
  13:         else
  14:             throw new ArgumentException
  15:                 ("Object is not a Customer", "obj");
  16:     }
  17: }

The breakdown looks a bit like this:


Line 8 – see if the object is null. If it is, move it to the top of the list.
Line 10 – convert the object to a customer
Line 11 – if it turns out that obj is a Customer, use the CompareTo method on String.
Line 13 – if it turns out that obj is not a Customer, throw an ArgumentException.


If we run the code again, we now get the result that we were hoping for:


Baxter, Dave
Harrison, Christopher
Ibach, Susan


Cool.


But…. If you look at the CompareTo implementation, we're having to cast the obj parameter to Customer. Why can't we just tell the IComparable interface that we want people to pass in a Customer and be done with it?


Fortunately – we can. The way that we do this is by using generics. In a nutshell, generics allow you to pass a type as you would a variable. So at design time we tell IComparable prepare itself for Customer objects. Let's update our Customer class again.



   1: public class Customer : 
   2:                 IComparable, IComparable<Customer>
   3: {
   4:     // existing code
   5:  
   6:     public int CompareTo(object obj)
   7:     {
   8:         // put all NULL objects at the top
   9:         if(obj == null) return 1;
  10:  
  11:         Customer otherCustomer = obj as Customer;
  12:         if(otherCustomer != null) // obj is a customer
  13:             return this.CompareTo(otherCustomer);
  14:         else
  15:             throw new ArgumentException("Object is not a Customer", "obj");
  16:     }
  17:  
  18:     public int CompareTo(Customer other)
  19:     {
  20:         // put all NULL objects at the top
  21:         if(other == null) return 1;
  22:         return this.LastName.CompareTo(other.LastName);
  23:     }
  24: }

I updated our original CompareTo method to call our new one. The new one is using the same logic as before, and running our code again returns the same result.


Cool – we have a Customer class that can be sorted.


But…. It can only be sorted one way – by LastName. If we wanted to sort by FirstName, well – that'd require updating our class. Having to update our class every time we need a different sort order would be a pain.


Fortunately – we don't have to. The .NET framework also includes an IComparer interface. The difference between IComparable and IComparer is that IComparable is for sorting that specific class (which is why Customer implemented IComparable), while IComparer is for sorting other classes – a utility if you will. Let's create a class that can sort Customer objects by FirstName.



public class CustomerSorter : IComparer<Customer>
{
    public int Compare(Customer lhs, Customer rhs)
    {
        // put nulls at the top of the list
        if(lhs == null) return -1;
        if(rhs == null) return 1;
            
        return lhs.FirstName.CompareTo(rhs.FirstName);
    }
}

The main difference, besides calling CompareTo on FirstName, is that we have two parameters of type Customer and we're comparing one to the other. But the logic is still basically the same.


To use the new sorter, we simply pass a new instance of the object into the Sort method on List.



// all other code identical
customers.Sort(new CustomerSorter());

When we run the code now, we get everything sorted by FirstName.


Harrison, Christopher
Baxter, Dave
Ibach, Susan


Cool.


But… If we have to create a new class every single time we need to change the sort order, well – that's going to stink. There's gotta be a better way.


Fortunately, there is. The .NET Framework gives us the ability to use delegates, which allow us to pass methods like we would objects.


Let's take a look at our new Compare() method that we created on our CustomerSorter class. You'll notice that it takes two parameters, each of type Customer, and returns an integer. That's it. And when we call Sort and pass in the CustomerSorter, it simply calls that method. Why can't we just pass a method into Sort?


This is where that delegate, an object that points to a method, comes into play. Since it can be used like an object and passed in as a parameter, we can just tell Sort to call that method directly. This is really the same thing we were doing before by passing in an instance of CustomerSorter to the Sort method, only this time we're just passing in a method.


Our method just needs to match the same signature – two Customer parameters and return an integer.


Let's add a method to our Program class that will use the same logic as our CustomerSorter.



// added to Program class
private static int SortByFirstName(Customer lhs, Customer rhs)
{
    // put nulls at the top of the list
    if(lhs == null) return -1;
    if(rhs == null) return 1;
    
    return lhs.FirstName.CompareTo(rhs.FirstName);
}

Want to know a secret? I simply copied and pasted from the CustomerSorter class and changed public to private , instance to static, and the name to SortByFirstName.


Now we just need to tell the Sort method to use our new SortByFirstName method.



// identical code except for Sort call
customers.Sort(SortByFirstName);

And as before, the result is the same – sorted by FirstName.


Cool.


But... If we need to sort in several different orders, we don't want to have to create a method each and every time. Wouldn't it be nice if we could just inject the logic right into the call to Sort?


Fortunately, we can. We do this by creating an anonymous method. An anonymous method is a method that has no name. We just create the method signature by using a delegate, and pass it right into the Sort method.



// identical code except for the Sort method
customers.Sort(delegate(Customer lhs, Customer rhs) {
    if (lhs == null) return -1;
    if (rhs == null) return 1;
 
    return lhs.FirstName.CompareTo(rhs.FirstName);
});

Just as before, we have the same logic (yes, I copied and pasted). We're just declaring the method just as we normally would with only a couple of differences. First, we're using the keyword delegate instead of using a method name. Second, we're not specifying a return type. The reason is that Sort already knows what the return type is – an integer – so the compiler doesn't require it.


And, as before, the result is the same – sorted by FirstName.


Cool.


But... Why do we have to specify the types of the parameters? After all, we already told the list right up front that we were using Customer objects.


Fortunately, we don't. This is where lambda expressions come into play. A lambda expression is just like an anonymous method, only with a couple more assumptions. In our case, since we know, and the compiler knows, that we are only dealing with Customer objects, and we need to return an integer, we're just going to declare our variables and move on.



// identical code except for call to Sort
customers.Sort((lhs, rhs) => {
    if (lhs == null) return -1;
    if (rhs == null) return 1;
    return lhs.FirstName.CompareTo(rhs.FirstName);
});

The main difference between this and our anonymous method is the syntax and the fact that we're not declaring data types. Since everyone, including the compiler, knows that lhs and rhs can only be Customer objects we don't have to declare it. The => is just the syntax to indicate the start of the method, or lambda expression.


And, as before, the result is the same – sorted by FirstName. Cool.


But... What about the normal situation where all we want to do is just say, "Hey .NET – sort this by ___ for me."? Do we really have to create a method, even in a lambda expression, every single time?


Fortunately, we don't. This is where Language Integrated Query (LINQ) comes into play.


In each of our method implementations, our code has simply taken advantage of the logic in the String class. LINQ will do the same thing for us. We simply tell LINQ, "Hey – sort by this", and it'll handle the translations for us.


The first step to using LINQ is to leave behind the Sort method that we've come to know and love. Unfortunately, Sort doesn't support LINQ.


When Microsoft introduced LINQ, they also introduced something called extension methods.[4] Extension methods are a way of adding a method to an existing class without having to inherit from that class. The method that was added to the List class, or more specifically IEnumerable, for LINQ was OrderBy.


With OrderBy we can, by using a lambda statement[5], simply tell LINQ the property we want to sort by. So the new code looks like this:



   1: // updating the foreach loop
   2: // all other code remains the same
   3: foreach (Customer customer in 
   4:             customers.OrderBy(c => c.FirstName)) {
   5:     Console.WriteLine(customer);
   6: }

Couple of things to notice here.


First up is that unlike Sort, OrderBy is volatile, meaning that it's going to return the sorted list rather than updating the list like Sort did.


Second is the fact that we're not returning an integer. Again, LINQ will handle the translation for us. As long as we specify a property that implements IComparable it will use that for the sorting.


Third is that LINQ uses deferred execution. In other words, it won't actually do the sort until we use the results. In this case, we're doing this when we use the foreach loop.


And now when we run the code we of course get the same results.


Cool.


And that's what that lambda statement is all about. It's really just letting someone else create the query for us based on a couple of assumptions about our code and the types that we're using.


From here, things actually get cooler. We of course have LINQ syntax, which allows us to write something similar to a SQL query. And, LINQ can also translate the queries for other environments, like SQL.


But for now, we'll leave it here, with a very propeller head view of lambda statements. Hopefully this helped bring together what's happening behind the scenes, and why we're able to take the shortcuts we can take.


And as always, if you want the source code, feel free.



[1] Or some variation of that syntax or that question.
[2] The one thing that might be unfamiliar is the <Customer>, or generics, syntax. We'll actually address that in a little while.
[3] Keep in mind this isn't a full implementation of IComparable. We really should implement IEquatable, and consider overloading the associated operators. But that's a topic for another blog post.
[4] Extension methods are worthy of another blog post.
[5] A lambda statement is just like a lambda expression – just one line instead of multiple lines.