Friday, December 21, 2007

WatiN testing ASP.NET - app startup time issues

I started a test project to test a web app. One thing I noticed was that due to application startup, occasionally the first couple of tests fail with TimeoutExceptions because the application takes too long to compile some of the pages.

So, I came up with the following to work around this:

using SHDocVw;
using WatiN.Core;
using WatiN.Core.Exceptions;

namespace Tests {
public class TestBase {
private static bool _siteSetupRun = false;

public TestBase() {
if (!_siteSetupRun) {
setupSite();
_siteSetupRun = true;
}
}

private static void setupSite() {
bool ok = false;
using (IE ie = new IE()) {
object nil = null;
((InternetExplorer)ie.InternetExplorer).Navigate("http://testsite/",
ref nil, ref nil, ref nil, ref nil);
while (!ok) {
try {
ie.WaitForComplete();
ok = true;
} catch (TimeoutException tex) {
if (!tex.Message.Contains("'Internet Explorer busy'")) {
throw;
}
}
}
}
}
}
}

This needs to run before any unit tests.

Sunday, December 9, 2007

Resolving extension method conflicts using a Proxy pattern.

If you happen to get this error: "The call is ambiguous between the following methods or properties: ...", here is how you would fix it:

Problem Setup


Lets say you are using the following library:

namespace PRI.Interfaces {
public interface IEntity {
string Name { get; set; }
}
}

namespace PRI {
public class DataEntity:Interfaces.IEntity {
public string Name { get; set; }
}
}

And the library authors decide to release an extension method (along with a couple of others you wish to use):

 
namespace PRI.Extensions {
    using PRI.Interfaces;
 
    public static class Entity {
        public static string CapitalizeName(this IEntity entity) {
            entity.Name = entity.Name.ToUpper();
            return entity.Name;
        }
    }
}

Meanwhile you are using a third party extension method library which already contains this method:

 
namespace Contoso.Extensions {
    using PRI.Interfaces;
    using System.Text;
 
    public static class Entity {
        public static string CapitalizeName(this IEntity entity) {
            StringBuilder sb = new StringBuilder(entity.Name.Length);
            string[] words = entity.Name.Split(new char[] { ' ' });
            foreach(string word in words) {
                sb.Append(char.ToUpper(word[0]));
                sb.Append(word.Substring(1).ToLower());
                sb.Append(" ");
            }
            entity.Name = sb.ToString().Trim();
            return entity.Name;
        }
    }
}


The Problem


This is a problem because you can no longer call the CapitalizeName method as an extension method if you happen to have both namespaces in your using constructs. As long as you are using functionality from both classes where the names of the methods are different you will not have any conflicts and there will not be any problems using your code. Unfortunately, the moment you add a call to the CapitalizeName method you will get a compile time error.


namespace Program {
    using System;
    using PRI;
    using PRI.Extensions;
    using Contoso.Extensions;
 
    class Program {
        static void Main(string[] args) {
            DataEntity dataEntity = new DataEntity() { Name = "frank smith" };
            dataEntity.CapitalizeName();
            Console.WriteLine(dataEntity.Name);
        }
    }
}

This will not compile because CapitalizeName cannot be resolved.

Enter the Proxy Pattern


Because extension methods are static methods and can be called just as any other static method gets called, you can build a wrapper class around these third party extension methods in order to resolve the conflicts that the method names impose.

namespace Program.ExtensionResolvers {
    using PRI.Interfaces;
 
    internal static class Resolver {
        public static string CapitalizeName(this IEntity entity) {
            return PRI.Extensions.Entity.CapitalizeName(entity);
        }
        public static string ConvertNameToTitleCase(this IEntity entity) {
            return Contoso.Extensions.Entity.CapitalizeName(entity);
        }
    }
}

Using the Solution


The extension method proxy class can now be used in order to resolve the naming conflict.

namespace Program {
    using System;
    using PRI;
    using ExtensionResolvers;
 
    class Program {
        static void Main(string[] args) {
            DataEntity dataEntity = new DataEntity() { Name = "frank smith" };
            dataEntity.ConvertNameToTitleCase();
            Console.WriteLine(dataEntity.Name);
        }
    }
}

Recommendation


If you are going to use more than 1 extension method library ever in the course of working on a project, I believe it is awfully important to encapsulate the extension methods you will be using into a proxy class (or several such classes) as I have shown here. It is probably best to keep this class internal as you wouldn't want to continue to pollute the function name domain to other third party libraries which are using your code.

I will argue that all calls to extension methods from third party libraries be internalized in this way. Doing so adds value (you can add xml documentation to these methods for your coworkers and the R# tools will be able to find usages and such) and it better decouples you from minor API changes in the extension libraries.

--
Thanks to Peter Ritchie on the altnetconf mailing list for most of the above code in the first section of this post.

Visual Studio 2008 first impressions

ok, ...

I will not be using VS 2008 until Resharper 4.0 EAP begins. I began starting to use 2008 this evening for my next post and I almost immediately realized just how dependent on R# I have become. As I began the first things I noticed (within the first 5 seconds) were:
  • Intellisense was different and I am not used to it.
  • I had forgotten where StringBuilder was located (R# will let you know when you reference a class that is not in a namespace you are using).
  • I really miss the error detection system.
  • Alt+Enter
  • F6
  • F2
  • Ctrl+B
  • Ctrl+T (I have binded this shortcut to Resharper.UnitTest.ContextDebug; more on that at some later time)
Other than that, I really liked my initial impressions:
  • Startup is much faster.
  • F1 doesn't hang VS for 5 minutes (I really hate this shortcut and I remove it from my system when possible because I tend to accidentally press it when going for F2 sometimes)
  • Hidden toolbox tabs show up faster when moused over.
  • Compilation seems faster.
  • VS seems to close faster.
So, in general, I really like it. Without R# I will not be using it.

Thursday, December 6, 2007

Job Hunting - questions to ask

Recently I asked a couple of questions openly to a person who posted a job offer* on the alt.net list which I think are important for discovering the attitude and environment of the potential employer.

These are more or less the questions I asked:
  • Does the company use OSS?

  • How does the company view OSS solutions?

  • Are you stuck with basic VS or do you get so use R# or the DevExpress plugins (or other productivity tools)?

  • Do your developers get to blog (or is that shunned)?

  • Are they allowed to work on OSS projects in their spare time?

  • Are they allowed to do so on company time for any projects the company (or even just the group) is using?

I believe these questions provide valuable insight into the employer.

*Note: I am not currently looking for a job, but if an offer comes up and it is significantly better than my current position I will look into it. It had better have a good pay raise, great benefits, not move me from Bozeman Montana, provide a flexible schedule, allow me to work from home when I want to and give me the flexibility to work on the projects I want to be working on. Ok, maybe that is a little exaggerated, but it had better be a very very good deal.

Tuesday, December 4, 2007

Object to DTO and back in an efficient manner

Reading Oren's post about converting an object to a DTO I got to thinking. Why do all that work of reassigning a bunch of properties if you can avoid it? The DTO is probably going to be serialized before being sent over the wire and only public properties are serialized; it doesn't make much sense to me to run a transform which would need to run at least 1 delegate (1 for every property to property transform), instantiate a new DTO, instantiate a List, instantiate an enumerator and enumerate over a list and instantiate a transformation class just to call a single method on it. It seems to me that most of this extra work can be avoided.

Here is a naive approach I would consider before running to lists of lambda expressions:

internal class DbOrder {
    public string Name;
    public int Id;
}
 
public class Order {
    private DbOrder _dbOrder;
 
    private Order(DbOrder o) {
        _dbOrder = o;
    }
 
    internal DbOrder DbOrder {
        get {
            if (_dbOrder == null) {
                _dbOrder = new DbOrder();
            }
            return _dbOrder;
        }
    }
 
    public string Name {
        get { return DbOrder.Name; }
        set { DbOrder.Name = value; }
    }
 
    public int Id {
        get { return DbOrder.Id; }
        set { DbOrder.Id = value; }
    }
 
    public static explicit operator Order(OrderDTO obj) {
        return new Order(obj.DbOrder);
    }
}
 
public class OrderDTO {
    private DbOrder _dbOrder;
 
    private OrderDTO(DbOrder o) {
        _dbOrder = o;
    }
 
    internal DbOrder DbOrder {
        get {
            if (_dbOrder == null) {
                _dbOrder = new DbOrder();
            }
            return _dbOrder;
        }
    }
 
    public string CustomerName {
        get { return DbOrder.Name; }
        set { DbOrder.Name = value; }
    }
 
    public int ID {
        get { return DbOrder.Id; }
        set { DbOrder.Id = value; }
    }
 
    public static explicit operator OrderDTO(Order obj) {
        return new OrderDTO(obj.DbOrder);
    }
}


The reason I would consider doing this this way is because both the Business class and the DTO class are nothing more than proxies to the data. Since this is the case, a Proxy pattern seems to me to be the best way to treat them.

Sunday, October 28, 2007

[altnetconf] RE: What is your current "task system" of choice, and how tied are you to it?

I was reading a post on the alt.net mailing list that just showed up on my inbox and thought it would be best to reply here:


We use Bugzilla for tracking everything that goes on with our applications. We have tried getting rid of it and failed too many times now (to replace it with JIRA, Fogbugz, mantis, SugarCRM, SalesForce and VSTS to name a few), there is just no better application. Bugzilla is not exactly what we want, but neither is anything else. We have since gotten rid of the idea of replacing Bugzilla and have integrated it with the rest of our processes. It receives commit messages from subversion; it will soon receive error reports directly from the application; we are looking into getting ccnet build reports to integrate into it. Our customer service had been using sharepoint to track and deal with their tasks, but they will soon be switching fully into Bugzilla. Our scrum board is nothing more than a shared search that looks at bugs that block a sprint tracker (this works really well as I work from Montana and the rest of the company is in Ohio, Pennsylvania and New Jersey and an actual whiteboard would be rather impossible). We now use it to do everything from manage releases to tracking defects and enhancements to track modifications made to the firewalls and network infrastructure to record helpdesk phone calls with their solutions.

Needless to say, our company runs off Bugzilla (yes, that takes BDD to a whole new level).

Even though it is not perfect and the imperfections are glaringly obvious (yet nearly impossible to explain how to fix), wherever it is good it is almost perfect. The perfect tools for this would fade into the background and no one would realize they were using them. It is very natural to use a buglist for the scrum board. It is also quite natural to commit a revision to subversion and have a bug get resolved as a side effect (well about as natural as the act of committing in subversion can be). Or to publish a release (another commit that goes against a different bug) then get up and go get a drink as CruiseControl.NET updates the qa environment and bugzilla resolves all the bugs waiting to get to qa, sending emails to the relevant testers that the issues are ready for them to verify, all without any user interaction (other than the commit).

What isn’t good about it is that anything that isn’t integrated or doesn’t have a natural appropriate workflow from the business perspective (regardless of the tool) is very difficult to get anyone in a habit of using (time tracking for example has not caught on despite the fact that we need to do it and know we have for the past 2 years). If the item that we try to quantify with Bugzilla is not a direct result or direct byproduct that appears on its own (even though it is something that can be figured out and we know how to do so) then it inevitably doesn’t get tracked.

Time tracking is an example there, but so are:
“What UI areas does issue X affect that will be visible to end users?”
“Does this issue need to be in release notes?”
“What was the outcome of meeting N on mm/dd/yyyy which related to this bug and why was implementation A taken over B?”
“What meetings has this bug been brought up in?”
“How much impact does this issue have with end users?”

We have been trying to figure out how to quantify those questions and many like them for several years and that is why we have tried other systems.

Additionally we have run into another issue which dwarfs the questions of this topic, as ultimately I feel that any of those systems could have wound up working for us (except VSTS, that one just didn’t fit the bill at all) had they been introduced at the right time (Bugzilla was introduced early and was simply leaps and bounds better than mere email), and that question is: “How do you deal with taking over another company that is at a different location and uses an entirely different task system?” The single biggest problem with Bugzilla at our company is that it isn’t enough to receive the corporate Buy-In from the higher ups in other locations who are already entrenched in a different system. It is far more important to be using a single task system companywide which works good for most things (and excels at a couple) than it is to sit down and figure out which system is best for you right now.

Wednesday, October 24, 2007

Schwartzian Transform in C# 2.0

In case someone was reading Joe Cheng's post about performing a Schwartzian Transform in C# 3.0 and was wondering what it would look like in 2.0 code, here it is:

private static void SchwartzSort<E, S>(List<E> list,
Converter<E, S> converter,
Comparison<S> comparison) {
    List<KeyValuePair<S, E>> pairs = list.ConvertAll<KeyValuePair<S, E>>(delegate(E x) {
        return new KeyValuePair<S, E>(converter(x), x);
    });
    pairs.Sort(delegate(KeyValuePair<S, E> x, KeyValuePair<S, E> y) {
        return comparison(x.Key, y.Key);
    });
    for (int i = 0; i < list.Count; i++) {
        list[i] = pairs[i].Value;
    }
}
 
/// <summary>
/// Sorts a list using a Schwartzian transform (applies a conversion
/// function to each element and sorts by the value of that function).
/// </summary>
/// <typeparam name="E">The type of element to be sorted</typeparam>
/// <typeparam name="S">The type of the element to sort by</typeparam>
/// <param name="list">The list to be sorted (sort occurs in place).</param>
/// <param name="converter">
/// The converter function (converts element of type <code>E</code> to type <code>S</code>).
/// </param>
/// <param name="comparison">
/// The comparison function, compares 2 values of type <code>S</code>.
/// </param>
/// <seealso cref="Sort{E,S}(List{E},Converter{E,S})"/>
public static void Sort<E, S>(List<E> list, Converter<E, S> converter, Comparison<S> comparison) {
    SchwartzSort(list, converter, comparison);
}
 
/// <summary>
/// Sorts a list using a Schwartzian transform using the default comparer
/// on type <code>S</code> (applies a conversion function to each element
/// and sorts by the value of that function).
/// </summary>
/// <typeparam name="E">The type of element to be sorted</typeparam>
/// <typeparam name="S">The type of the element to sort by</typeparam>
/// <param name="list">The list to be sorted (sort occurs in place).</param>
/// <param name="converter">
/// The converter function (converts element of type <code>E</code> to type <code>S</code>).
/// </param>
/// <seealso cref="Sort{E,S}(List{E},Converter{E,S},Comparison{S})"/>
public static void Sort<E, S>(List<E> list, Converter<E, S> converter) where S:IComparable {
    SchwartzSort(list, converter, delegate(S x, S y) { return x.CompareTo(y); });
}



Obviously this is not quite as aesthetically pleasing as the 3.0 version, but it is still useful for any developers doing 2.0 coding out there and need to sort a list by the results of a function. Here is an example of how it would be used:



public class foobar {
    private string _foo;
    private string _bar;
 
    public string Foo {
        get { return _foo; }
        set { _foo = value; }
    }
 
    public string Bar {
        get { return _bar; }
        set { _bar = value; }
    }
 
    public foobar(string foo, string bar) {
        _foo = foo;
        _bar = bar;
    }
}


Assuming class foobar:



List<foobar> items = new List<foobar>(4);
items.Add(new foobar("a","b"));
items.Add(new foobar("asdf","jkl"));
items.Add(new foobar("green","purple"));
items.Add(new foobar("c", "a"));
 
Sort<foobar,string>(items, delegate(foobar item) { return item.Foo; });

Wednesday, October 3, 2007

Colors

I don't know about these colors. I know I didn't like what was there before, but I don't have any idea if this is any good now. I do like this layout much better. But, I don't know much of anything about these colors because I am colorblind. I think some of the borders and such are a shade of green on the blog side and I don't know how well they go together. I suppose I will be trying to figure this out for a long time. Any help would be appreciated. Also, ignore the image colors, they were there before. I will get to them at some point.

Some sites I used to help get myself this far with the colors:

Read only source?

ScottGu on releasing read only source code for .NET 3.5

I don't know about this. I will not be looking at any code under the MS-RL. It seems like having that license makes the code supplied under it bait. I wonder how it will affect the number of contributors to mono? Once you look at the Microsoft .NET source, you can no longer contribute to mono.



It seems like embrace, extend, extinguish to me. First Microsoft embraces all developers by making it really easy to look at and use the source for the framework. They continue working on it to build up libraries for anything imaginable. Then a few years later they bombard open implementations and competitors with the full force of their legal department. Or worse, they eat up so much of the development pool that there is no one left to compete with them, they get in with colleges to use their implementation and have people write books about it, etc. And I was beginning to think the MS dev offices were a whole different better side of MS.



Kudos to the hard working guys at MS who got it this far, but I am unsure that this is far enough.

Sunday, September 30, 2007

My frist psot.

Ok, so not quite that exciting; would have expected the url to be taken though, but alas, it is mine now. So what is this going to be? Well it should be whatever I feel like. I expect mostly C#, OOP and asp.NET in particular because that is my job at the moment, but whatever I feel like ranting about I guess.

About me:
  • I live in Bozeman, Montana.
  • I work in Stroudsburg, Pennsylvania (yeah, thats something of a commute!).
  • I am a software developer, mostly writing C# for a couple asp.net applications and a large library, but I occasionally do some perl, php, vbscript, c++, ....
  • I like to solve problems (hence I am a programmer).
  • I love to read (this whole blogosphere has me hooked, I am subscribed to several hundred blogs and blog aggregations and I read every post, about 80 posts a day, and that ignores the books I am reading [right now, The Martians, The Salmon of Doubt and Professional DotNetNuke 4]).
  • I enjoy snowboarding, hiking, swimming, and generally being outside.
  • I graduated college with 3 degrees (Computer Science, Computer Security and Mathematics) because I was bored for the most part and the school I went to did not have, nor did I know to look for, adequate research opportunities.
  • I would like to go on for my PhD in CS in the hopes of furthering research in the field and better educating future persons in the profession.
  • As for research areas I have always been particularly interested in parallel computing and compiler construction (esp. compiler optimizations for parallel environments and languages for such), but I have been recently coming to enjoy the field of software engineering and the interaction I see it should be having with logic. I have a couple of ideas started for various papers/books I intend to get to writing and I hope the fact I just wrote that provides me the push I need to complete them.
Hmm, that was a bit more than I expected to write. No more misspelled titles to reference slashdot though I think.