Speaking at New Mexico .NET User Group

On Thursday, 4/2/09, I’ll be speaking at the New Mexico .NET User Group.  It will be one of my favorite topics, Practical LINQ.  They’ll be giving away a copy of my latest book, LINQ Programming, too.  If you can make it, stop by, say "Hi!", and we’ll have a great time talking about LINQ and .NET development.

Initial Thoughts on RIA Services

At Mix 09, Microsoft unveiled RIA Services.  Subsequent blog entries from Nikhil Kothari and Brad Abrams provide good introductions.  In a nutshell, RIA Services is a framework for making it easy to build a middle-tier for RIA applications, such as Silverlight.  RIA Services makes it easy to communicate with the server and provides other essential services, such as validation and asynchronous processing.  Not that you can’t do this today with Web Services, but RIA Services does a lot of this work for you.  In my case, it also lets me code business logic the way I’m accustomed, with business objects, yet does all of the plumbing work that I really don’t want to do. If you’re interested, download the bits and check them out.  Remember, this is Early Beta and you should install it on either a virtual machine or a computer designated just for test software.

Brad Abrams on LINQ Support

In his blog post, Framework Design Guidlines: LINQ Support, Brad Abrams say’s "DO implement IEnumerable<T> to enable basic LINQ support"; This is very good advice for anyone building a framework, API, or custom collection.  I was recently using a 3rd party API where the collections did not implement IEnumerable<T> or IEnumerable.  Even if they are IEnumerable (non-generic) you can still use the collection with LINQ like this:

customerArrayList.Add(new Customer { Name = "Jack" });
customerArrayList.Add(new Customer { Name = "Allison" });
 
var customers =
      from Customer cust in customerArrayList
      where cust.Name.EndsWith("on")
      select cust;Console.WriteLine(cust.Name));

customers.ToList().ForEach(cust =>

var customerArrayList = new ArrayList();

 
If you’ve become accustomed to using LINQ to manipulate collections, you’ll definitely feel like you’re missing something without it.  In my case, I wanted to do set operations with query operators like Except and Union.  Here’s a summary of what the 3rd party API looked like:
 
Each of the collection classes implements a separate interface, which is key to finding a solution for using LINQ.  Here’s an example of the interface:
 

public

interface ICustCollection
{
      Customer GetAt(int index);
      int GetCount();
}
 
Notice that the interface doesn’t have standard .NET IEnumerable members like MoveNext and Count.  Here’s an implementation of that interface:

public class CustomCustCollection : ICustCollection

{

      // customer collection stuff
      public Customer GetAt(int index)
      {
            // whatever internal implementation they have
            // – could possibly be from a COM interop scenario
            return new Customer();
      }
 
      public int GetCount()
      {
            return 1;
      }
}

The preceding code isn’t a full implementation and only serves as stub code to support what I’m going to show you later.  With this API, you would use the following for loop to access the contents of the collection:
 

ICustCollection custColl = new CustomCustCollection();
 
// add some stuff to cust Coll
for (int i = 0; i < custColl.GetCount(); i++)
{
      // do something with custColl, 
      // assuming it has members
}
 
If you’re accustomed to being able to use foreach or (better) LINQ, the code above is probably pretty ugly and cumbersome, especially when you have some serious filtering or collection manipulation to do.  So, I decided that I wanted these collection classes to be IEnumerable<T> and solved the problem with Extension Methods.  Here’s how I added an extension method to ICustCollection, so that I could translate the results into List<T>, which is IEnumerable<T>:

public static class ThirdPartyApiCollectionExtension

{

      public static List<Customer> ToList(this ICustCollection custs)
      {
            var custList = new List<Customer>();
 
            // build a List<CustomCustCollection> from custs
            for (int i=0; i < custs.GetCount(); i++)
            {
                  custList.Add(custs.GetAt(i));
            }
 
            return custList;
      }
}
 
Notice that both the class, ThirdPartyApiCollectionExtension, and the method, ToList, are static.  Also, notice that the first parameter (only parameter in this case) is ICustCollection, modified with the this keyword to specify that ToList extends ICustCollection.  The implementation of ToList simply extracts everything from custs and returns it as a List<Customer>.  Now, I can use LINQ on the data like this:

ICustCollection custColl2 = new CustomCustCollection();

List<Customer> custList = custColl2.ToList();

var newCustomers =
      from cust in custList
      where cust.Name == "Jack"
      select cust;
 
Notice how the preceding code calls ToList on custColl2.  That’s because custColl2 is ICustCollection and ToList is an extension method that operates on ICustCollection, as described for the ThirdPartyApiCollectionExtension class above. 

If you follow Brad Abram’s advice, you’ll make it easy for people to use your API. Of course, if you’re on the receiving end of a non-IEnumerable<T> API, you can use the work-around above.

Rocky Mountain Tech Tri-Fecta

The Rocky Mountain Tech Tri-Fecta is a *free* conference that includes sessions in the areas of Windows, SQL Server, and .NET.  It will be held in downtown Denver on Feb 21st.  I’m scheduled to present a session titled "LINQ to Twitter: Building a Custom LINQ Provider", but there are many more sessions all day by people that are both local and ones you see presenting at regular conferences.  Here’s the link for more info:
 

Local Database Cache and |DataDirectory|

Every once in a while it’s easy to get sidetracked by something that is totally irrelevant to what you are trying to accomplish.  Case in point is the Local Database Cache, where the wizard generates a *.sdf (compact framework database) at the top level of your solution.  When you start working with your code, its easy to look at the *.sdf at the top level of your solution and say “That’s where my database is”.  One might even be tempted to add a reference to the database (located at the top level of the solution) through Server Explorer, making it easier to observe changes while configuring synchronization and testing an occasionally connected client.

The problem occurs when writing code to execute synchronization and testing to verify that all is set up properly.  When verifying, its easy to open the *.sdf through Server Explorer to verify that synchronization was successful, but the changes aren’t there.  This sets off a sequence of debugging code to verify that changes are being made and there aren’t any errors or exceptions.  When the code looks and runs perfect, one would verify that the database being looked at at is the same one in the solution. Perhaps a few random queries on search engines would be appropriate too, yielding nothing.  After having checked the connection strings, which were autogenerated, it might become apparent that the location of the database isn’t necessarily the same as what the connection string indicates, especially since the Data Source contains the |DataDirectory| macro.

As it turns out, there is an *.sdf file in appDir/bin/Debug.  Considering the |DataDirectory| in the connection string, the following blog post that explained this situation quite well:

http://blogs.msdn.com/smartclientdata/archive/2005/08/26/456886.aspx

By default, |DataDirectory| means that the local database cache will be created in the same location as the *.exe, which is where all of the updates occur.  Therefore, setting Server explorer to look at appDir/bin/Debug/*.sdf does the trick.  Of course, changing the project configuration from Debug to Release would mean that the database would be in appDir/bin/Release/*.sdf.  The post describes ways to alter this location, but the default behavior seems fine for most scenarios; especially attractive is the smart client scenario where you really don’t know the physical location of the *.sdf until runtime.

Going back to the original distraction motivating this blog post, it might be best to delete the *.sdf created by the Local Database Cache wizard; Otherwise, someone might accidentally think the *.sdf at the top level of the solution is the client database cache and waste their own time in a manner described in this post. 😉

Membership.GetUser Returns null in the Login Control’s LoggedIn Event

Ran into a glitch where I couldn’t retrieve the MembershipUser during the LoggedIn event.  I wanted to cache some info in Session that I would be using on multiple pages.  Yeah, I know about the tradeoffs of keeping info in Session state, but I wanted to it anyway. 😉  Normally, passing the user name should work, like this:

MembershipUser user = Membership.GetUser(LoginCtrl.UserName);

Problem was that the UserName property of LoginCtrl (the Login control reference) was blank, resulting in a null return value.  This is weird because the UserName is normally available during this event.  As it happens, User.Identity.Name was blank also; Too strange.

After Live Searching (hmm, lacks the ring of Googling) the following blog entry revealed the culprit:

http://www.codeplex.com/cssfriendly/WorkItem/View.aspx?WorkItemId=7187

To summarize, the link describes a bug in the CSS Friendly Control Adapters where the UserName and Password aren’t set if you switch the Login control to use templates.  So, here’s the fix:

string userName = (LoginCtrl.FindControl(“UserName”) as TextBox).Text;

MembershipUser user = Membership.GetUser(userName);

Needless to say, a CodePlex issue got my vote. 🙂

LINQ to Twitter v0.20 Released

I just released v0.20 of LINQ to Twitter.  This release includes support for User queries, such as Followers, Friends, and Show.  This was an interesting deployment for me because it fleshes out the Strategy pattern for managing different types of queries.  There were three parts of the code I needed to modify: (1) add an IRequestProcessor derived type for User queries, (2) Add a Users property to TwitterContext for to return a TwitterQueryable<User>, and (3) add the User query type to the Simple Factory used to get an IRequestProcessor.  The rest of the code operates on IRequestProcessor and other stuff, but I didn’t need to touch it.