Hugoware

The product of a web developer with a little too much caffeine

Archive for September 2009

Combining WebServices with MVC

with 7 comments

I always liked the concept behind WebServices. Having a single place to store a bunch of complex but commonly used functions is a great way to decrease complexity of other programs that all sit on the same network. If you’re like me and tend to do a lot of intranet applications, a web service can prevent a lot of duplicate code.

My only real problem with WebServices was having to use SOAP. Adding a Web Reference to a project wasn’t that big of a deal but if you ever wanted to just call a function real quick, say from a script file (yes, I do VBScript occasionally… ick) then it isn’t quite as I’d prefer. You end up spending more time making sure your XML is well formed and less time on the logic inside your quick script.

MVC helps get around that problem by allowing you to perform normal HTTP calls and plug all your arguments into the query string or the body of the request – something much easier to do. The problem, however, is that you end up losing the convenience of using a WebService with other applications.

A Simple Solution

The idea here is to create a controller that acts as a wrapper to a WebService. By doing this we can override a few methods on our Controller that use reflection to invoke the matching method on the WebService. Also, because the Controller is still a unique class, we can still attach any number of Actions to it as we normally would. Below is some code that I wrote the other day. It isn’t battle tested so if you use it be sure to verify it does everything that you need it to do.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Mvc;
using System.Reflection;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.IO;

namespace Interface.Controllers {

    /// <summary>
    /// Abstract wrapper that handles calling WebService methods on behalf of a controller
    /// </summary
    public abstract class WebServiceControllerWrapper<T> : Controller where T : WebService {

        #region Constructors

        /// <summary>
        /// Creates a new Controller Wrapper for a WebService
        /// </summary>
        public WebServiceControllerWrapper() {
            this.Service = Activator.CreateInstance<T>();
        }

        #endregion

        #region Properties

        //The service that is being used for this call
        private T Service { get; set; }

        #endregion

        #region Overriding Methods

        //finds the correct method for the WebService method
        protected override void HandleUnknownAction(string actionName) {

            //find if the method exists
            MethodInfo method = this.Service
                .GetType()
                .GetMethods()
                .Where(found =>
                    found.IsPublic &&
                    found.Name.Equals(actionName, StringComparison.OrdinalIgnoreCase) &&
                    found.GetCustomAttributes(typeof(WebMethodAttribute), true).Count() > 0
                    )
                    .FirstOrDefault();

            //if no method was found, just give up
            if (method == null) { return; }

            //check if all the arguments were found
            List<object> arguments = new List<object>();
            ParameterInfo[] parameters = method.GetParameters();
            foreach (ParameterInfo param in parameters) {

                //check if this argument was found
                object arg = this.ValueProvider[param.Name].ConvertTo(param.ParameterType);
                arguments.Add(arg);
            }

            //with the arguments try and call the result
            object result = method.Invoke(this.Service, arguments.ToArray());

            //if there is a return value, serialize it and write it
            this.Response.ContentType = "text/xml";
            if (method.ReturnType != null) {

                //if this is an XElement of some kind, just use it as is
                if (result is XObject) {

                    //write the string
                    using (StreamWriter writer = new StreamWriter(this.Response.OutputStream)) {
                        writer.Write(result.ToString());
                    }

                }
                else {

                    //try and serialize it
                    XmlSerializer serialize = new XmlSerializer(result.GetType());
                    serialize.Serialize(this.Response.OutputStream, result);
                }

            }

        }

        #endregion

    }

}

The idea here is to inherit this class instead of the standard Controller class and provide the name of the WebService we want to wrap around as our Generic argument. For example…


//that's about it - actions are mapped automatically to the correct method on the webservice
public class AccountController : WebServiceControllerWrapper<AccountWebService> { }

By doing this, when our controller receives an Action, is checks the WebService instance for the same method and then tries to call the method with the arguments it finds as part of the request!

And that’s it! A quick and simple way to map incoming actions to a matching method on a Web Service!

The Return Type

I’m not sure the best way to handle the return type at this time. It seems to me that the XmlSerializer should be sufficient for object with the exception of Xml which should probably just be written out as a string. If you have a suggestion on a better way to respond to incoming requests, please let me know. 🙂

Remember: This is just some quick and dirty code – This needs some more polish and exception handling before I’d use it in a real project, but at least it might help you get going in the right direction.

Written by hugoware

September 27, 2009 at 9:51 pm

Slightly Easier Recursive Functions

leave a comment »

I’ve joked before that recursive functions were the kind that make you “curse over and over and over and over…”. Granted, they aren’t the most difficult thing to do in programming, they can tend to require a little more focus to write correctly.

So when you work with a recursive function you normally need to create some sort of safety counter to prevent an infinite loop. If not you end up passing around your counter by reference which can be a bit confusing to developers in itself.

Not only that, it also tends to hurt the “black box” approach to class design. Even if the method is private you still need to prepare a safety counter in advance before you can call the method — a function that has a order dependency, which isn’t a good thing.

Lambda To The Rescue

I love working with lambdas – I think that I cried a tear of joy the day I realized they could be passed as an argument (actually, I didn’t… that would be weird).

So what if we created a single lambda within our functions that would perform all of the recursive logic inline?

public void ScanElements(XElement xml) {
    
    //create a safety counter
    int safety = 0;
    
    //declare the scan action as null at first
    //since we can't call it recursively inside
    //the method unless it is declared first
    Action<XElement> scan = null;

    //assign the actual work to do
    scan = (node) => {

        //increment the safety
        if (safety++ >= 100) { return; }

        //do the actual work here
        Console.WriteLine(node.Name);

        //and then recursively call the scan method again
        foreach (XElement element in node.Elements()) {
            scan(element);
        }

        //reverse the safety
        safety--;

    };

    //now, actually start the recursive function here
    scan(xml);

}

Now, that isn’t too bad. We have all of our logic encapsulated into a single method that doesn’t require any setup before it is used. It might be a little odd to a developer that hasn’t used lambdas much, but a comment explaining what is going on should be enough to get them onto the right track.

Maybe this is a terrible idea – I’m not really sure but it does decrease complexity and improve encapsulation — even if it is with a single private method.

Using the .Descendants() method as part of the XElement/XDocument classes would be much wiser here – this code is just an example of performing a recursive method.

Written by hugoware

September 24, 2009 at 10:33 pm

Programming – AKA: Paint By Number

with 7 comments

This last week has been pretty busy for me. I’ve been working on several projects at work, deadlines coming due, trying to get personal projects done, jLinq bugs fixed — it’s been a rough week.

I was excited a few weeks ago when the new developer was going to start. I was finally going to be able to spread out some of this work and get a little more time on my hands… or so I thought. As it turns out, this guy isn’t exactly what I was expecting. Despite my best efforts, I still ended up hiring someone with pretty much no background in programming. I went from already being maxed out to now spending between 20% to 30% of my time teaching the basics of programming… yeah – this is my fault.

But as bad as it sounds it really has actually helped me rediscover a programming rule that I thought I was still using but apparently had forgotten.

So, one of the first projects the guy had to do involved checking a directory for new files, creating a record of the file if it was found and then processing existing files to transform file types from one to another. Really, probably an hour long job at most but was really causing this guy some grief.

An Alternate Approach — Simplicity

Naturally, as a developer, the first thing I started trying to explain was how the code would work like checking file dates or creating an XmlSerializer to load and save files — none of which actually helped him solve his problem. After several frustrating whiteboarding sessions I came up with a new route — make it so simple it was impossible to mess it up!

I took a second pass at trying to get the guy started in the right direction. Instead, I opened a new class file for him and wrote something like this.

public class FileRecordSync {
    //snip...

    //This is a list of the files that the program has already detected
    //this is also where to add new files that are discovered
    public List<FileRecordEntry> CurrentFiles { get; private set; }

    //determine if this file should be processed or not
    public bool IsValidFileType(string path) {
        throw new NotImplementedException();
    }

    //check and see if this file exists in CurrentFiles or not
    public bool IsExistingFileEntry(string path) {
        throw new NotImplementedException();
    }

    //check to see if the modified date is greater than the logged modified date
    public bool IsFileEntryModified(FileRecordEntry entry) {
        throw new NotImplementedException();
    }

    //find the matching file in the CurrentFiles or return null if nothing was found
    public FileRecordEntry FindExistingEntry(string path) {
        throw new NotImplementedException();
    }

    //create a new FileRecordEntry from the path and add it to CurrentFiles
    public void AddNewFileRecordEntry(string path) {
        throw new NotImplementedException();
    }

    //set the file as expired to 
    public void MarkFileAsModified(FileRecordEntry entry) {
        throw new NotImplementedException();
    }

    //snip...
}

Granted, an experienced developer could place all of those functions into a single loop and it would still be readable but isn’t the code above the kind of code we should all be writing anyways? Simple, clear, straight-forward functions each with a specific purpose and nothing more?

Code like this manages complexity – he didn’t have to worry about how each of the functions were going to fit into the master plan but instead how to complete each of the functions.

You know what coding like this makes me think of – Paint by number! And when it comes to code complexity – that’s a VERY good thing.

paint-by-number

It’s hard to tell what that is a picture of looking at it now — but if you remain diligent and fill in each of the blanks with the correct color then before long you’re staring at a masterpiece (or maybe not — this picture looks like someone holding a gun in FPS view — but you get the idea :))!

When it was all said and done with, the loop that had caused so much grief was much easier to read – not just for him but easier for me to read as well!


public void ProcessFiles() {

    foreach(string file in Directory.GetFiles(folder)) {

        if (!this.IsValidFileType(file)) { continue; }

        if (this.IsExistingFileEntry(file) &&
            this.IsFileModified(file)) {
            FileEntryRecord entry= this.FindExistingFile(file);
            this.MarkFileAsModified(entry);

        }
        else {
            this.AddNewFileRecordEntry(file);

        }
    }

}

Even without comments, you can most likely figure out what this code does with only a cursory glance over it.

A Personal Reevaluation

Its hard to say when a developer abandons simplicity. I think a lot of us start out writing gigantic functions that do much more than they need to and then slowly realize how much easier our lives are if we create functions for specific jobs.

Ironically though, I think the smarter and more skilled we become, we begin to lose sight of what a “simple” function really is. Some of us can write a single lambda expression to create a ham-n-cheese sandwich with our eyes closed — a 20 to 30 line for loop can’t possibly be that difficult for us anymore!

I can’t deny that I would have pushed all that code into a single loop, used a handful of well named variables with a couple clear and useful comments and called it a day. But looking back on the final result I can say without a doubt that I’d rather go back and make changes to the new, simpler class — wouldn’t you say the same?

Written by hugoware

September 17, 2009 at 10:17 pm

Have You Said ‘Thank You’ Lately?

leave a comment »

It’s always fun to look back on your career and see where you were and how you got to where you are now. Its also interesting to see the points where your life took the big turns, normally from a single moment or discussion with another person.

I’m not talking about the ‘Big Guys’ like Hanselman or McConnell (order is random ;)). I’m talking about the little moments that happened from parents, bosses or just people we met along the way.

Without these events we might be using different languages, working with different technologies — Heck, we might not even be programmers anymore. It seems to me we ought to thank those people that helped guide us to where we are today – even if it was inadvertently…

My Thank You List

Mom
Got me a programming book for our Commadore 64 when I was 6, fixed the computer every time I screwed it up, kept me focused on art and design.

Dad
Brought home my first “real” programming language Toolbook from Asymetric – Wasn’t playing with a kid language anymore (…well, I was, but you get what I mean)

Larry W.
The company I worked at didn’t have a software development department when I arrived – Without this guy I wouldn’t have a job (or even had the chance to learn all I’ve learned)

Gary W.
Probably said the most important statement in my professional career – “Classic ASP? I was under the impression that all real software development was done using either .NET or Java!” — or something like that. In any case, that was the kick in the pants I needed to really try and become a professional.

The Wife
Where do I get the time to blog? Or work on my projects? Or do contract work? Or listen to me sort out a problem when she really just doesn’t care that I think that an implementation of some WebControl is poorly designed? Without my best friend I wouldn’t have ever had the time. (Someone needs to keep the brats away :))

Cheesy But Relevant

Yeah, this is kinda a cheesy, out of the blue, mushy blog post – but take a moment and really think about it. You are where you are because someone helped you make that decisions – even if by accident.

So? Who do you need to go tell ‘Thank You’?

.

Another Icon

reflector

Made another icon real quick today – I didn’t like the existing Reflector icon (since it looked terrible on my dock). I made a quick on to tide me over until I can make a nicer looking one.

Written by hugoware

September 11, 2009 at 2:11 am

Double Whammy – jLinq Release And Screencast!

with 2 comments

Now that you’re all excited time for some disappointment – it is just a minor update to fix a few bugs and to add one new feature.

But instead of just blogging about it I’ve also done a new screencast to talk about the updates and new feature in this release.

  • Dynamic Queries (using OR) – Before, if you used “OR” at the start of a query then you’d get an exception. jLinq would try and tag “||” at the start of your query which would cause the whole thing to collapse. Now, jLinq correctly handles this and prevents the error. In turn, writing dynamic queries just got a whole lot easier!.
  • Range Comparisons With Dates – Version 2.2.0 introduced smarter comparisons by evaluating the types of values being passed in instead of expecting only one type. However, in the change, the range comparisons like greater, less, between, etc, would all incorrectly evaluate Dates as strings… bummer.
  • Bitwise Flag Comparisons – jLinq 2.2.1 introduces a new query method called has which performs bitwise flag comparisons on records. It even works with regular ol’ numbers by converting them before performing the comparisons.

Anyways, go check out he new screen cast now and tell me what you think!


screencast-4-play

Bonus: CamStudio Icon

camStudioExample

Last night while I was setting up CamStudio for this screencast I was looking at their UGLY icon they use for their program — I just couldn’t stand it being in my beautiful RocketDock – so I designed a new one for them. If you’re looking for an improved logo then you can download the PNG for the CamStudio icon.

Written by hugoware

September 9, 2009 at 2:18 am

iPhone vs BlackBerry – A Developer’s Tale – Part 1

with 9 comments

Here is the plan: Develop two mobile apps, one for BlackBerry and one for iPhone at the same time to see what is easier for a .NET guy to whip out — then blog the whole thing into a series of posts! Brilliant!.

Crazy – You Bet!

So the original project was simply to develop an iPhone app but I figured that since I was putting so much work into the mobile web service why not do two apps at the same time! Since most of the heavy lifting is going to be done by using C# and ASP.NET MVC then It shouldn’t be that hard — will it?

For this series of posts I’ll be keeping track of the iPhone development using my MacBook Pro using Xcode and Objective-C and the BlackBerry development using my Dell XPS using Eclipse and Java. I’m going to try and keep track of the hours spent – but I can guarantee I won’t have a stop watch with me at all times.

Let’s see what happens!
versus

Getting Set Up

This post is probably isn’t going to be very interesting since this mainly goes over getting the two environments setup. You’ve been warned! 🙂

[BlackBerry – 2.5 hours]

Since programming with BlackBerry uses Java I immediately downloaded the latest version of Eclipse along with the SDKs from the BlackBerry website. I got everything downloaded and installed in less than 40 minutes (even though the BlackBerry website wasn’t the easiest thing to navigate)!

So I fired up an instance of Eclipse and started a new project — and… uh… what the heck? My keys aren’t working? I tried closing and reopening and rebooting — nothing! The keys simply would not respond. As it turns out the problem was the BlackBerry SDK itself! Basically, the newest version of Eclipse wasn’t supported so that meant I had to find a previous version (3.4) and use it instead — bummer.

So after downloading Eclipse (again) I was ready to go. I started a BlackBerry project, pasted in some sample code to play around with, hit run and — CRASH! I’ll save the dramatics here but basically the UAC in Vista was kicking in and causing the emulator to die. Disabling it fixed the problem (but turned off UAC which isn’t what I wanted… but oh well). I had considered reverting this back to my VM of Ubuntu but since I had already invested so much time I figured I’d just stick with it.

After I finally figured out how to get the emulator started then it wasn’t long before I had my first “Hello World” program running and the BlackBerry was in business! Not too bad!

[iPhone 4.5 hours]

My new Mac came in the other day and I was ready to get started. Downloading the correct Xcode was a little confusing at first but once I got it figured out I had it up and running without any of the problems I had with Eclipse (although it was a 2GB download – whoa!)

The whole Mac keyboard/touch pad thing is terrible if you’re used to using keys like END, HOME or Right-Clicking (which I’m assuming developers use quite often :)). Even things as simple as resizing a window are painful on a Mac – but really its irrelevant for this discussion.

As s C# developer it wasn’t hard to look at Java code and get a general idea of what was going on. Even the entire Eclipse IDE acts similar to Visual Studio so the learning curve was greatly reduced… but Objective-C… not so much…

I read the documentation on the Apple website several times, watched a couple terrible screencasts and poked around with the Xcode IDE and still nothing. If you haven’t ever seen Objective-C before, make sure to shield your eyes when you do. I can pretty much guarantee it won’t make a bit of sense.

Also, the Apple documentation made some bizarre suggestions on the correct way to define methods… Check out this little gem here…

…method names should interleave the name with the arguments such that the method’s name naturally describes the arguments expected by the method. For example, the Rectangle class could instead implement a setOriginX:y: method that makes the purpose of its two arguments clear…

What? Name your method to emphasize the first argument? Would Steve McConnell approve of this?

Project Status

BlackBerry (3%): IDE installed and sample is working!

iPhone (1%): IDE installed but haven’t been able to understand any of the code yet.

Currently, BlackBerry has the lead with the least development time invested. In fact, the BlackBerry is up and running with a sample application. But after looking at the designer for the iPhone interface it looks like once I get past the initial Objective-C hurdle then development may move a long much faster than I anticipated. Will BlackBerry maintain the lead or will the iPhone catch up? Check back for the rest of the series!

Written by hugoware

September 7, 2009 at 2:11 am

Tool List Mania!

with one comment

Not sure if everyone else has been noticing this but a lot of devs have been developing lists of their favorite tools. While I’m not calling myself a “famous dev”, I do think that I’ll join in party!

ClipX – Clipboard Manager

clipx

Seriously, this tool ranks as one of my favorites – it’s such an amazingly useful concept executed with simplicity and elegant… or something like that. Basically, Copy as much as you want and even use your Paste command like you normally would. But if you need something from your history press Shift+Paste and BAM! A list of previously copied text and images – Awesome!

Notepad++ – Simple, Clean, Excellent

notepad

The classic Windows Notepad has served us well but all things must pass. Notepad++ is actually a bit of a misnomer if they are trying to describe how much better it is compared to regular Notepad. It should be something like Notepad+x42, but you get the idea anyways.

One of the reasons why this Notepad sets itself apart from others is it’s Word Completion “intellisense” – basically it uses the words already in your document for the auto-complete text, which is surprisingly useful!

notepad-word-complete

Expresso – Makes Me Think Of Coffee

expresso

There is probably thousands of Regular Expression tools out on the web that people all love – my personal choice has always been Expresso. I’m not sure if its the tools, that its free or a sub-conscious choice since I like coffee so much. Regardless, Expresso has been in my toolkit for a long time now and until someone else comes up with another coffee flavored named version, I’m sticking with it.

RocketDock- My Personal Apple Indulgence

rocketdock

Yeah, this looks like the application launcher for the enemy but it is still one of my favorite ways to get access to my most commonly used applications. Windows 7 might change my mind but for now this is hard to beat. You can even download additional plug-ins that can create the same “fan” style folder list! Awesome!

Like most tools, there are a lot of other options out there, but RocketDock is the only one that consistently placed the window focus on programs I launched, which was pretty much the most important part of the whole thing for me. 🙂

.NET Reflector – Pure AWESOME

reflector

I’m shocked when I encounter a developer that hasn’t heard of Reflector – but then again all of us, at one point or another, never knew about it. Even though you probably know all about it I’m going to list it just in case. If you ever need to see what the source of compiled .NET code looks like this is the tool.

jLinq- Personal Plug

jlinq

It’s like LINQ with your JSON data! Brilliant! Someone needs to get this guy a raise! In all seriousness if you’re going to be doing a lot of work with JSON data, especially large arrays of records, then jLinq will go a long way to help you keep your code short and clear!

n52te – Bonus Hardware Section

n52te

If you like gaming then you might want to check this out – the n52te. It is hard to see how I used to play games in the past before this came along. When I get this thing configured I can do 66+ commands reliably all with my left hand! Your keyboard certainly can’t do it!

I also use this thing for work from time to time, interestingly enough. For example, I have a separate configuration for using Blender (3D modeling program) that makes it easier to navigate the application. (I’m not good at 3D modeling, just something I do for fun)

In fact this is my second time buying this – I used to own its baby brother – until he died (granted it took a lot of abuse before it did).

And For Your Viewing Pleasure

You may have come here today looking for .NET programming related content… sorry… But how about a .NET related LOL-Cat?

lolcat

Written by hugoware

September 4, 2009 at 2:19 am

Build A Smarter Loop With C#

with 3 comments

One of the first things every programmer learns in how to loop through an array of information. We learn how to do for, foreach, while loops but then we never really improve on them. For the most part the standard loop is as far as a programmer goes.

It seems to me that loops should be more intelligent than that. In fact we often write code that uses the loop for additional information. It isn’t uncommon to see a loop check if it is an even or odd index or the first or last value.

Modestly Smarter Loops

I really like lambdas a lot – in fact probably, too much. Being able to pass an delegate around like an argument definitely can be abused but in some cases it can make for some really elegant code. Let’s look at some code that can improve working with arrays.

namespace LoopExtensions {
//Some comments removed for brevity...

    #region Extension Methods

    /// <summary>
    /// Handles looping through collections with additional details
    /// </summary>
    public static class LoopExtensionMethods {

        public static IEnumerable<T> Each<T>(this IEnumerable<T> collection, 
            Action<ElementDetail<T>> each) {
            return LoopExtensionMethods.Each<T>(collection, 0, collection.Count(), each);            
        }

        public static IEnumerable<T> Each<T>(this IEnumerable<T> collection, 
            int start, 
            Action<ElementDetail<T>> each) {
            return LoopExtensionMethods.Each<T>(collection, start, collection.Count(), each);
        }

        public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
            int start,
            int end,
            Action<ElementDetail<T>> each) {
            Action<ElementDetail<T>, T> handle = (detail, item) => { each(detail); };
            return LoopExtensionMethods.Each<T>(collection, start, end, handle);
        }

        public static IEnumerable<T> Each<T>(this IEnumerable<T> collection, 
            Action<ElementDetail<T>, T> each) {
            return LoopExtensionMethods.Each<T>(collection, 0, collection.Count(), each);            
        }

        public static IEnumerable<T> Each<T>(this IEnumerable<T> collection, 
            int start, 
            Action<ElementDetail<T>, T> each) {
            return LoopExtensionMethods.Each<T>(collection, start, collection.Count(), each);
        }

        public static IEnumerable<T> Each<T>(this IEnumerable<T> collection, 
            int start, 
            int end, 
            Action<ElementDetail<T>, T> each) {

            //verify the ranges
            if (start < 0 || end > collection.Count()) {
                throw new ArgumentOutOfRangeException();
            }

            //perform the work
            foreach (T value in collection) {
                each(new ElementDetail<T>(value, start++, end, collection), value);
                if (start == end) { break; }
            }
            return collection;
        }

    }

    #endregion

    #region Detail Information Class

    /// <summary>  
    /// Contains a summary of information about the item current in the loop  
    /// </summary>  
    public class ElementDetail<T> {

        #region Constructors

        internal ElementDetail(T value, int index, int total, IEnumerable<T> collection) {
            this.Value = value;
            this.Index = index;
            this.Total = total;
            this.Collection = collection;
        }

        #endregion

        #region Loop Information

        public int Index { get; private set; }

        public int Total { get; private set; }

        public T Value { get; private set; }

        public IEnumerable<T> Collection { get; private set; }

        #endregion

        #region Value Properties

        public T Previous {
            get {
                return !this.First
                    ? this.Collection.ElementAt(this.Index - 1)
                    : default(T);
            }
        }

        public T Next {
            get {
                return !this.Last
                    ? this.Collection.ElementAt(this.Index + 1)
                    : default(T);
            }
        }

        public bool Last {
            get { return this.Index == (this.Total - 1); }
        }

        public bool First {
            get { return this.Index == 0; }
        }

        public bool Outer {
            get { return this.First || this.Last; }
        }

        public bool Inner {
            get { return !this.Outer; }
        }

        public bool Even {
            get { return this.Index % 2 == 0; }
        }

        public bool Odd {
            get { return !this.Even; }
        }

        #endregion

        #region Collection Properties

        public int StepNumber {
            get { return this.Index + 1; }
        }

        public float PercentCompleted {
            get { return (((float)this.Index / (float)this.Total) * 100); }
        }

        public float PercentRemaining {
            get { return 100 - this.PercentCompleted; }
        }

        public int StepsCompleted {
            get { return this.Index; }
        }

        public int StepsRemaining {
            get { return this.Total - this.Index; }
        }

        #endregion

    } 

    #endregion

}

Now that is a lot of code but if you review over it you’ll find that it is a set of extension methods that can be used with IEnumerable. The basic idea is that we can perform our loop within a delegate that accepts additional information about the elements in our loop.

So here is a quick example…

string[] items = {
    "Apple",
    "Orange",
    "Grape",
    "Watermellon",
    "Kiwi"
};

items.Each((item) => {
    Console.Write("{0} > ", item.Inner ? "Inner" : "Outer");
    if (!item.First) { Console.Write("Previous: {0}, ", item.Previous); }
    Console.Write("Current: {0} ({1})", item.Value, item.StepNumber);
    if (!item.Last) { Console.Write(", Next: {0}", item.Next); }
    Console.WriteLine(" -- {0}% remaining", item.PercentRemaining);
});

// Output
// Outer > Current: Apple (1), Next: Orange -- 100% remaining
// Inner > Previous: Apple, Current: Orange (2), Next: Grape -- 80% remaining
// Inner > Previous: Orange, Current: Grape (3), Next: Watermellon -- 60% remaining
// Inner > Previous: Grape, Current: Watermellon (4), Next: Kiwi -- 40% remaining
// Outer > Previous: Watermellon, Current: Kiwi (5) -- 20% remaining

Normally you would simply write all the comparisons within your loop and then use them as needed. Instead, in this code, we pass in an additional parameter that contains shortcuts to many common comparisons you might find inside of loops. By doing this we improve readability and focus on what the loop is doing.

Whats Wrong With The Old Way

Nothing! Writing your comparisons inline can be advantageous since you aren’t doing any more work than you need to do. However, in some cases, the improved readability would make a big difference in the quality of the code. Consider the two snippets of MVC code and decide with one is easier to read.

<ul>
<% foreach(SiteMapNode node in breadcrumb) { %>
    <li class="item <% =(breadcrumb.IndexOf(node) % 2 == 0 ? "item-even" : "item-odd") %>" >
    <% if (breadcrumb.First().Equals(node) || breadcrumb.Last().Equals(node)) { %>
        <strong>
    <% } %>
        <a href="<% =node.Url %>" >
            (<% =(breadcrumb.IndexOf(node) + 1) %>) : <% =node.Text %>
        </a>
    <% if (breadcrumb.First().Equals(node) || breadcrumb.Last().Equals(node)) { %>
        </strong>
    <% } %>
    </li>
<% } %>
</ul>

Or the same code using a loop helper…

<ul>
<% breadcrumb.Each((node) => { %>
    <li class="item <% =(node.Even ? "item-even" : "item-odd") %>" >
    <% if (node.Outer) { %><strong><% } %>
        <a href="<% =node.Value.Url %>" >
            (<% = node.StepNumber %>) : <% =node.Value.Text %>
        </a>
    <% if (node.Outer) { %></strong><% } %>
    </li>
<% }); %>
</ul>

This example shows using only the ElementDetail class but of course you could use the other extension method that also supplies the value by itself.

Write Code For Humans Not For Computers

Everyone has heard the advice before – more or less, readability is probably the most important part of your code. The computer can read both of those examples easily whereas a human might need to think for a moment before they are positive what the code does.

In any case, this simple but effective approach can transform previously unreadable code into works of programming art… or something like that…

Written by hugoware

September 2, 2009 at 2:12 am