Archive for category .NET Development

ToList() or not ToList(), that is the query.

A lot has been written about the nature of deferred execution with regards to LINQ queries, so I won’t go into it in detail here, suffice to say it’s nice when you can retain this behaviour as it usually makes your code more efficient. It can however come at a cost and here’s an example of why:

var query = from customer in db.Customers 
            where customer.City == "Paris" 
            select customer;
if (!query.Any()) << Query Executes Here
{
    Console.WriteLine("No results found");
    return;
}

foreach (var customer in query)  << And Query Executes Again Here
{
    Console.WriteLine(customer.CompanyName);
}

You have to make a choice here, read all results of query into a list up front with a call to ToList(), which could take a while before it starts writing out to the console (due to network IO or whatever), or you can execute the query twice. (as seen above)

Why not have the best of both worlds?

What we really want is an alternative to ToList() which still defers the execution and reads from the query as it iterates, but persists the results in subsequent iterations so that the heavy lifting only happens once (just like ToList()).

To achieve this I implemented an IEnumerator<T> called BufferedEnumerator<T> which wraps an inner enumerator and buffers the results as calls to MoveNext() are made against it, until the inner enumerator has been fully buffered and we can dispose it. To provide the BufferedEnumerator<T> I implemented an enumerable called BufferedEnumerable<T>.

One thing to note is that we don’t dispose the inner enumerator because we might not be finished with it. This raises an issue, if we don’t Dispose it when the Dispose() method is called, then when do we Dispose? The way I chose to get around this was to make the BufferedEnumerable<T> disposable and have it call the inner dispose, this means to be clean and tidy you should really wrap the buffered result in a using statement or call Dispose on it when you’re done (to ensure any underlying query is not left open etc).

Using the new Buffered() extension method

var query = from customer in db.Customers 
            where customer.City == "Paris" 
            select customer;

using (var buffer = query.Buffered())
{
    if (!buffer.Any()) << Query starts executing here
    {
        Console.WriteLine("No results found");
        return;
    }
    foreach (var customer in buffer) << Same query continues executing here
    {
        Console.WriteLine(customer.CompanyName);
    }
}

The good news is this can now be used as a 100% replacement to ToList(), you get none of the negative side effects of ToList() executing when it may not be necessary or reading all of the results when only the first result will do. Just remember that it is truly deferred, if you call query.Buffered() and never iterate over it, the query will never be executed.

Enjoy!

Download Source

Leave a comment

Use of the flux capacitor causes ‘ASP.NET Ajax client-side framework failed to load.’

Our company is preparing for a move of hosting companies from Brisbane to the U.S. Whilst working with the Beta server I hit a snag… ASP.NET Ajax kept giving me a JavaScript error on one of our apps. I knew this was an issue with loading the ScriptResource.axd files from the server, but what was confusing me was that another application in another virtual directory of the same web site was using this AJAX stuff and working perfectly.

After using Fiddler2 to see the real problem with loading the ScriptResource.axd, i saw that the response contained this error message:

Specified argument was out of the range of valid values. Parameter name: utcDate

So after a lot of Googling dead-ends I finally found an article titled ScriptResource.axd and assemblies built in the future which explains the issue. Essentially my mistake was that I had incorrectly been using the Flux capacitor as a part of my build process and had been building the binaries about 20 hours in the future, my bad…

The way I resolved this issue was to not Zip up my binaries before FTP’ing them up to the server so that the FTP server would reset the created and modified dates. Issue fixed…

Leave a comment

Building a Modern User Interface with Expression Design, Blend and WPF

Recently I attended Microsoft’s Re-mix 08 in Melbourne, and one of the goodies they gave me as a reward for filling out a survey was $1000 worth of Microsoft Expression designer products.  So I felt it would be kind of wasteful not to be using this software despite the fact that I’m not a designer by trade, I’m a software developer through and through.

I have, however, been wanting to create a user interface that totally broke away from the boring business forms of my day-to-day and create something funky, something cool, something I would love to use, and (secretly) love showing off to my friends.

And so, starting with Expression Design, here’s what I came up with:

Muse Layout

Now looking at this you might think this is a media player of some kind, and you’d be right… sort of… It’s actually going to be a music learning tool for myself. My memory is notoriously bad when it comes to remember chords for playing songs on guitar, (a fact which everyone in the band I play in would quite strongly attest to). Some of the problem is a lack of motivation, and a lot of it is just plain poor memory. So I thought a funky app to play along with might up the effort.

(Insert comment here about irony in wasting time creating the app (and writing this blog about it) instead of practicing)

The idea is that I have MP3 files of the songs I need to learn and TAB or CRD files I’ve downloaded off the Internet. What I want is to have the application prompt me with chords as I play along to the track, perhaps even shoving a few lyrics in my face at the same time to really get the brain-association flowing. What I need, however, is a way to sync the music and the chords, this is where the Record button comes in. I simply click record, and using the keyboard or mouse, tap away the chords as the music plays and the timing gets saved away for the next time I hit play on that song.

Anyway now that I have the concept done, and I have a design sort of figured out (and yes I drew those buttons myself by hand), on with development of the app.  This brings me to a common problem, I’ve used Expression Design (which is basically MS’s attempt at a sort of cut-down Adobe Illustrator). But Expression Design doesn’t do User interfaces it does illustrations… or does it… If I select File / Export…

File \ Export... 

and change my Export format to XAML…

Change Export Format to XAML Canvas

Click Export All and BAM!! A User interface… man this is scarily easy… and what’s really scary is how good the output looks in Expression Blend 2.

image

I now have an exact replica of my design in a WPF application… "Yeah sure" I hear you say. "But it’s still just pretty pictures, they don’t actually do anything".

Well that’s pretty easily rectified… Select my play button for starters… select Tools / Make Button

image

Click ok and now it’s a button that works… of course I need to make it glow when hover over it and stuff but it’s all so much easier than it used to be (and so much more powerful than CSS and Html). I’m in heaven…

2 Comments

ASP.NET’s ObjectDataSource not calling SelectMethod in Insert mode

I’m going nuts… I have an ASP.NET page that I’ve added a DetailsView, being the good little programmer I am, I’m trying to grok the ASP.NET 2.0 way of databinding everything using ObjectDataSources (as I know how bad not being able to use proper data binding in ASP.NET 1.1 was for productivity)

But these productivity gains I’m hoping to see are not materializing, I’m trying to make the page create a new item, but I want the DetailsView to have a list of default values in each of the fields. Our Business Logic provides a CreateObject function that instantiates an object with system defaults. But apparenlty ObjectDataSource doesn’t support default values. Select never gets called with the Mode for the DetailsView is in Insert.  WHY MS?? WHY!!!

Investigating this it seems I’m not alone in my pain, but their solution is far from what I’m after… time to re-implement ASP.NET’s functionality (ASP.NET 1.1 pain all over again).

Update: I’ve come up with a simple solution!
Ok, this is solved fairly simply just by having DefaultMode="Edit" set on your DetailsView and having your DataSource with the following:  SelectMethod="GetOrCreate" UpdateMethod="AddOrUpdate".

The above functions can just be logic that looks at your input parameters and calls the appropriate method.

So in summary, as far as I’m concerned, never set DetailsView’s mode to Insert… it’s useless.

1 Comment

Adding a Closing EventHandler in WCF makes Username Read Only

Ok, here’s another weird experience, I’ve been building a static class to cache my WCF Service Clients so that they could be used efficiently in ASP.NET. It’s basically contains Dictionary<TKey, TValue> of Services against a list of service types. This was all working perfectly, but I thought I’d add some logic to remove references to any services that were not closed by my cache class. To do this I added a ICommunicationObject.Closing event handler to my cache when I created a new instance of the service.

Example

private static T CreateService<T>() where T : class, ICommunicationObject, new()
{
    List<ICommunicationObject> list = null;
    lock (clientsSyncRoot)
    {
        if (ServiceClients.ContainsKey(typeof(T)))
        {
            list = ServiceClients[typeof(T)];
        }
        else
        {
            list = new List<ICommunicationObject>();
            ServiceClients.Add(typeof(T), list);
        }
    }
    T obj = new T();
    obj.Closing += new EventHandler(Service_Closing);
    list.Add(obj);
    return obj;
}

private static void Service_Closing(object sender, EventArgs e)
{
    ICommunicationObject serviceClient = sender as ICommunicationObject;
    if (serviceClient == null)
        return;
    lock (clientsSyncRoot)
    {
        if (OpenClients.Contains(serviceClient))
        {
            OpenClients.Remove(serviceClient);
        }
    }
}

This had the oddest behaviour of locking my service client’s .ClientCredentials.UserName property, marking it read-only and threw an exception ‘Object is Read Only’, ensuring I could never set the credentials for my Service. I still have not figured out why this happens, but removing the Closing event handler fixed it again… I give up…

1 Comment

Fixing FindControl in ASP.NET 2.0 and ASP.NET 3.5

After becoming used to having really powerful common functions built for your ASP.NET 1.1 apps, it’s very easy to forget they aren’t a part of the .NET Framework when you start a new project. One such common function I never realised I needed so much was a proper FindControl function.

Every ASP.NET developer defines a DataBound control with some kind of custom template at some point in their life. So how do you get at those controls in your fancy template at run time? Logically you would think FindControl would nail this requirement. Unfortunately it doesn’t really, so if you find yourself calling TextBox t = myListView.FindControl("TextBox1") as TextBox and getting nowhere, try this handy class:

using System.Web.UI;
public static class ControlHelper
{
    /// <summary>
    /// Performs a recursive FindControl returning a strongly typed object
    /// </summary>
    /// <typeparam name="T">Control Type to return</typeparam>
    /// <param name="parentControl">The Control to search from</param>
    /// <param name="id">The ID of the control you're looking for</param>
    /// <returns></returns>
    public static T FindControl<T>(Control parentControl, string id) 
where T : Control { Control found = parentControl.FindControl(id); if (found != null) { return (T)found; } foreach (Control ctrl in parentControl.Controls) { if (ctrl != null) { found = FindControl<T>(ctrl, id); if (found != null) { return (T)found; } } } return null; } public static T Find<T>(this Control parentControl, string id)
where T : Control { return FindControl<T>(parentControl, id); } }

Viola!

The cool thing about this function is I’ve made it support being used as an Extension method (Remove the bottom function if you aren’t running .NET 3.5), it’s recursive, and also it returns a strongly type object (because the System.Web.UI.Control type is useless on it’s own)

Now you can call myListView.Find<TextBox>("TextBox1");

Much neater!

Leave a comment

Automated Unit Tests and the Dreaded Random Data

Recently I’ve been reviewing some unit tests for one of our major projects. And a coding practice I have noticed in these tests has started to annoy me. Sadly I am the one to blame for this coding practice, as I started it, but it is one that I hope to fix for all future tests (and some of the old ones). It is the use of random data in an automated test case. This practice emerged from our tests needing be repeatable on a system that has unique constraints on certain tables in the database, such as a Username, the test cases would randomly generate a valid username and register the user as a part of the test. Ok this is fine, but then the practice spread to all data being put into the system, including measurements, dates company names, even phone numbers. We wrote functions to create valid random data, and even randomly pick codes.

This gives great looking test data not just for your automated tests but also for any user-interactive testing etc. The problem for me lies in the fact that in a Unit Test you want to keep your variables to a minimum. A well designed Unit Test should be repeatable now or 10 years from now giving exactly the same results every time you run it. It should be able to specifically check that certain things do or do not happen. When random data is used for values that the test depends on, this can lead to tests giving false negatives, or worse, false positives (but only some of the time).

Example

   1:  [Test]
   2:  private void UpdateUserAge()
   3:  {
   4:      Random rand = new Random();
   5:      User user = UserData.GetUserByID(1);
   6:      int originalAge = user.Age;
   7:      user.Age = rand.Next(100);
   8:      UserData.UpdateUser(user);
   9:      User updatedUser = UserData.GetUserByID(1);
  10:      Assert.AreNotEqual(originalAge, updatedUser.Age);
  11:  }

In this example, a simple function gets out a User by ID 1 from a database (please ignore the fact the ID is hard-coded), updates the Age in the database with a random number between 0 and 100 and checks that the UserData.UpdateUser() function properly performed the update.

So what’s wrong with this code?

Well imagine that the UpdateUser function accidently ommitted the Age property in it’s updates (this actually happened to us a while back where a field was added to a database but it was left out of the update logic). Roughly 1 in 100 times this function would give a false positive that the updateUser.Age was correctly changed. Now if you were unlucky enough to have this occur when you were initially developing you may never have noticed that UserData.UpdateUser() did nothing.

Ok, this is a simple example but it can show how your Unit Tests are creating (or hiding) bugs of their own. Here’s the point I’m trying to make… Go to the effort of setting up a known scenario for your test, then change that known scenario, and double check everything equals what you expected it to. In the above example I’m also assuming an existing User… what if two developers were running this test at once? Create the data from scratch, it makes your tests larger (much larger) and if this becomes a problem create an ordered test where the scenario is created for a whole suite of test cases, that are run in sequence.

Leave a comment