# Friday, April 03, 2009

Are Microsoft really starting to turn a page when it comes to Open Source? Let’s hope so; they’ve just released the source code to the (excellent) ASP.NET MVC framework under the OSI-approved MS-PL license. There's more information over at Scott Guthrie’s blog – I’d particularly recommend reading his ASP.NET MVC PDF tutorial as it gives an excellent overview of ASP.NET MVC itself.

posted on Friday, April 03, 2009 7:11:17 AM UTC  #    Comments [0] Trackback
# Wednesday, March 25, 2009

One of the nice features introduced into Java 1.5 that is missing in C# is enum types. In C#, enums are nothing more than a defined set of values with labels, whereas in Java enums can contain methods. I've seen a few attempts to mimic Java enums in C#, but most solutions seem to rely on Attributes to decorate the enum which is fine except that in relative terms, reflection operations are expensive.

C# 3.0 introduced the concept of extension methods which enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. As is my wont, I was thinking about this in the shower this morning when I had a eureka moment - surely it should be possible to fake Java enums using C# extension methods?

Using the Java planets example, it didn't take long to whip up the following:

using System;
using System.Collections.Generic;

namespace ScratchPad
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var p = new Program();
            p.Run();
        }

        private void Run()
        {
            double earthWeight = 175;
            double mass = earthWeight / Planet.Earth.SurfaceGravity();

            foreach (Planet planet in Enum.GetValues(typeof(Planet))) {
                Console.WriteLine("Your weight on {0} is {1}", planet, planet.SurfaceWeight(mass));
            }
        }
    }

    public enum Planet
    {
        Mercury,
        Venus,
        Earth,
        Mars,
        Jupiter,
        Saturn,
        Uranus,
        Neptune
    }

    public static class PlanetExtensions
    {
        private static readonly Dictionary<Planet, PlanetData> planetMap = new Dictionary<Planet, PlanetData>
          {
              {Planet.Mercury, new PlanetData(3.303e+23, 2.4397e6)},
              {Planet.Venus, new PlanetData(4.869e+24, 6.0518e6)},
              {Planet.Earth, new PlanetData(5.976e+24, 6.37814e6)},
              {Planet.Mars, new PlanetData(6.421e+23, 3.3972e6)},
              {Planet.Jupiter, new PlanetData(1.9e+27,   7.1492e7)},
              {Planet.Saturn, new PlanetData(5.688e+26, 6.0268e7)},
              {Planet.Uranus, new PlanetData(8.686e+25, 2.5559e7)},
              {Planet.Neptune, new PlanetData(1.024e+26, 2.4746e7)}
          };

        private const double G = 6.67300E-11;

        public static double Mass(this Planet planet)
        {
            return GetPlanetData(planet).Mass;
        }

        public static double Radius(this Planet planet)
        {
            return GetPlanetData(planet).Radius;
        }

        public static double SurfaceGravity(this Planet planet)
        {
            PlanetData planetData = GetPlanetData(planet);

            return G * planetData.Mass / (planetData.Radius * planetData.Radius);
        }

        public static double SurfaceWeight(this Planet planet, double mass)
        {
            return mass * SurfaceGravity(planet);
        }

        private static PlanetData GetPlanetData(Planet planet)
        {
            if (!planetMap.ContainsKey(planet))
                throw new ArgumentOutOfRangeException("planet", "Unknown Planet");

            return planetMap[planet];
        }

        #region Nested type: PlanetData

        public class PlanetData
        {            
            public PlanetData(double mass, double radius)
            {
                Mass = mass;
                Radius = radius;
            }

            public double Mass { get; private set; }
            public double Radius { get; private set; }
        }

        #endregion
    }
}

It's all very simple; the only drawback is that you must remember to match any changes to your enum in the associated extension class. Overall, I think this is a pattern I might start to use more often.

posted on Wednesday, March 25, 2009 10:23:36 AM UTC  #    Comments [0] Trackback
# Thursday, October 04, 2007

Scott Guthrie's blog entry "Releasing the Source Code for the .NET Framework Libraries" details how Microsoft are finally going to allow access to the .NET framework source code without having to resort to using Lutz Roeder's fantastic Reflector utility - under the terms and conditions of the Microsoft Reference License.

To their credit, Microsoft are not claiming that this is an open source license; although naturally some on Slashdot are seeing this as further proof of that Microsoft == Satan (you'll find the discussion here: http://developers.slashdot.org/article.pl?sid=07/10/03/1626209&from=rss)

Anyway, it does look being yet another compelling reason to move to Visual Studio 2008 when it finally gets released (along with .NET Framework 3.5 support, and the ability to target .NET Framework 2.0/3.0/3.5 from within the same IDE - about time too...)

posted on Thursday, October 04, 2007 1:12:45 PM UTC  #    Comments [1] Trackback
# Friday, December 08, 2006

I shouldn't have got myself so wound up about the 70-536 exam I did this morning. The 'real world' questions were not nearly as bad as the Training Kit had me expecting, and there certainly weren't any howlers like the example I posted yesterday, so it came as a great relief to pass comfortably.

Mind you, it looks like I'm not the only one to have issues with the quality of the official Training Kit.

 

posted on Friday, December 08, 2006 12:03:01 PM UTC  #    Comments [0] Trackback
# Thursday, December 07, 2006

I'm sitting the 70-536 (Microsoft .NET Framework 2.0 – Application Development Foundation) exam tomorrow, and I sincerely hope that it's of a higher quality than the learning materials Microsoft provide for it. I've been testing myself using the official MCTS 70-536 Training Kit, and running the example tests provided.

What's disconcerting is that some of the questions are just plain wrong; here's an apposite example:

Which of the following code samples is the most efficient and compiles correctly?

  1. string s = null;
    s = "Hello";
    s += ", ";
    s += "World";
    s += "!";

  2. string s = null;
    StringBuilder sb = null;
    sb = "Hello";
    sb += ", ";
    sb += "World";
    sb += "!";
    s = sb.ToString();

  3. string s = null;
    StringBuilder sb = null;
    sb.Append("Hello");
    sb.Append(", ");
    sb.Append("World");
    sb.Append("!");
    s = sb.ToString();

  4. string s = null;
    s = "Hello";
    s += ", ";
    s += "World";
    s += "!";

So what's the correct answer? Not only do we have two identical options (1 and 4), but they also happen to be the only ones that will compile and execute. 2 is wrong because StringBuilder doesn't accept the "=" or "+=" operators, and 3 also shares the problem that the StringBuilder is never instantiated. Guess which option the test exam says is correct?

Can't say it fills me with much confidence for tomorrow...

posted on Thursday, December 07, 2006 10:45:24 AM UTC  #    Comments [3] Trackback
# Monday, November 20, 2006

Last week, Microsoft quietly released Windows Powershell 1.0 (formally known as Monad) to the world. This is a great piece of technology that's worth taking some notice of - it's destined to become my Windows shell of choice; at least when a version for Vista is released. As it is, I'm stuck using it on my development laptop (running XP SP2). Previously, if I needed to do any form of complex scripting on a Windows box, I'd install Cygwin and knock something up in bash. Powershell will now take preference however; it ties in the .NET Framework with a scripting environment, so it gives me a library that I'm already familiar with (and one that I'm likely to be staying with for some time). As a quick example, how to display the number of days until Christmas using Powershell:

[String]::Format("{0} days until Christmas!", ([DateTime]"25 Dec 2006" - [DateTime]::Now).Days)

That's not to say that Cygwin is coming off my systems any time soon, I like having the GNU toolchain available (I'd be lost without rsync, ssh and wget), but for day to day scripting it'll be Powershell.

When it's available for Vista that is!

posted on Monday, November 20, 2006 1:44:38 PM UTC  #    Comments [1] Trackback
# Thursday, June 15, 2006

Amongst the many roles I seem to undertake at my current employer (.NET Evangelist, NHibernate Evangelist, ATLAS Evangelist and so on), I also spend a large amount of my time dealing with XML technologies - whether it be transformation, serialization, querying or whatever.

Over time I've seen some truly awful implementations of so-called XML 'solutions'; one of my favourites involved the DVLA here in the UK. They proudly announced that they'd implemented an XML based system to enable the querying of Driving Licence details (whether the driver was banned, how many points on the licence and so on). So, given an XSD schema describing the object graph required for the query I coded up a simple .NET application to produce the correct XML fragment.

The DVLA instantly rejected it because:

  1. Every element needed to start on a new line
  2. There was an 'encoding' attribute in the XML declaration
  3. Even though the source XSD had specified a target namespace, namespace declarations were not understood

Aaaargh!

Even worse was the size of the response - every single line in the response document was padded to over 200 characters, and with one element on each line this produced a document that was 62,771,702 bytes long.

A simple

cat results.xml | tidy -xml -indent -o parsed.xml

produced a document that was a mere 8,604,602 bytes in length.

Now this is a bit of an extreme example, but I've seen several variations along this theme in active use and nearly all of them stem from one single problem - string concatenated XML, like this:

Console.WriteLine(@"<?xml version='1.0' encoding='utf8'?>");
Console.WriteLine("<root><element attribute='value' /></root>");

XML has a problem in that it is very easy to read and understand, but there are enough pitfalls for the unwary/lazy. I've had documents in the past where the encoding has been specified as UTF-8, but the characters supplied have been ISO-8859-1 which lead to some truly awful hacking with 'awk' and 'sed' later in a complex overnight batch process.

The MSDN article "Five Ways to Emit Test Results as XML" by James McCaffrey provides some interesting XML generation options for the .NET framework which I fully agree with - except for the end of Technique 1.

There are many, many toolkits out there for XML processing and generation - don't resort to string concatenation, you'll get it wrong!

posted on Thursday, June 15, 2006 10:59:06 AM UTC  #    Comments [0] Trackback
# Wednesday, August 31, 2005

If you can read this, my domain has been successfully transferred from wwwserver to Netcetera. Whilst wwwserver provide an incredibly cheap Asp.NET hosting service and a very intuitive management system, their helpdesk support leaves a whole lot to be desired.

When a customer registers a problem on an automated helpdesk system, it is entirely unacceptable that the issue remains unanswered 48 hours later. At the very least acknowledge to the customer that the problem is being looked into, rather than leaving them wondering what on earth is going on.

As it is, I've lost two full days worth of emails in as many weeks due to their Email Forwarding service failing.

Sometimes cheap is not cheerful.

posted on Wednesday, August 31, 2005 11:55:52 AM UTC  #    Comments [0] Trackback
# Tuesday, February 22, 2005

Spent my first day at DevWeek 2005 today, and I have to admit my brain seems fit to burst this evening. John Robbins was the keynote speaker this morning, giving a general talk on the new features in VS.NET 2005. I have to admit that if I was one of the developers behind ReSharper (the development tool for VS.NET 2003) I'd be seriously worried. All the refactoring tools in VS.NET 2005 seem to be heavily influenced by, if not directly copied from ReSharper (or at a push, Eclipse).

I spent the rest of the day being lectured by (and asking far too many akward questions of) Jeffrey Richter. His first two sessions were connected with the new features in C# 2.0 of which I'll blog about more later.

What was more worrying was what was mentioned almost in passing during his Exceptions lecture (which was in itself fascinating); .NET Remoting is dead - or at least not promoted any more by Microsoft. I'll have to get Ingo Rammer's take on this tomorrow as he's one of the speakers here. It's a shame if this is correct, as the last major project we completed at IS Solutions would not have been possible (or at least would have been even more painful than it was already) if .NET remoting wasn't as well designed as it is.

 

posted on Tuesday, February 22, 2005 9:46:54 PM UTC  #    Comments [0] Trackback
# Tuesday, October 12, 2004

A project I'm currently working on for my employer using ASP.NET 1.1 requires a coherent mechanism to maintain a consistent look and feel throughout the entire site. Now, as ASP.NET 2.0 isn't here yet (Master Pages would have been a perfect fit for this project) I decided to use a mechanism based on URL rewriting.

In short, all the main 'page' functionality is contained within User Controls. There is a single .aspx page that loads the required user control and instantiates it for display within the HTML template. Using a regular expression based url rewriter mechanism this templating system is hidden from the end user; for example, a request for:

http://localhost/MyApplication/MyPage.aspx

is mapped under the hood to:

http://localhost/MyApplication/Template.aspx?UserControl=Controls/MyPage.ascx

All well and good - I had the basic URL rewriting mechanism in place in a couple of hours, and the start of a working template mechanism a couple of hours after that. However, then the problems started cropping up.

The first major issue cropped up with postbacks. In short, they didn't work. The reason for this is that the ASP.NET framework fills in the action attribute with a canonicalized path to CurrentExecutionFilePath, which is not what's wanted here.

Easy then - change the action in the template page. Wrong; whichever brain dead idiot designed the System.Web.UI.HtmlControls.HtmlForm class hid the implementation of the action attribute. So, you've got to jump through hoops to change the functionality.

My eventual solution was to subclass the HtmlForm and replace the instance in my template page with my new class, ActionForm. ActionForm overrides the RenderAttributes function, which creates a new HtmlTextWriter, my own subclassed ActionFormHtmlTextWriter. This class in turn overrides WriteAttribute which checks to see what attribute it's writing out - if it's "action", then the value is changed to the originally requested Url. Control is then passed back to the original HtmlTextWriter to write the value out. Anyway, if it gets someone else out of the mire, then great.

public class ActionForm : HtmlForm
{
    protected override void RenderAttributes(HtmlTextWriter writer)
    {
        string action = (string)Context.Items["VirtualUrl"];

        if (action == null)
        base.RenderAttributes(writer);

        using (ActionFormHtmlTextWriter virtualWriter = new ActionFormHtmlTextWriter(writer))
        {
            virtualWriter.ActionUrl = action;
            base.RenderAttributes(virtualWriter);
        }
    }

    private class ActionFormHtmlTextWriter : HtmlTextWriter
    {
        private string actionUrl;

        public ActionFormHtmlTextWriter(HtmlTextWriter writer) : base(writer)
        {
        }

        public ActionFormHtmlTextWriter(HtmlTextWriter writer, string tabString) : base(writer, tabString)
        {
        }

        public string ActionUrl
        {
            get { return actionUrl; }
            set { actionUrl = value; }
        }

        public override void WriteAttribute(string name, string value, bool fEncode)
        {
            if (value != null && String.Compare(name, "action", true) == 0)
                value = ActionUrl;

            HtmlTextWriter writer = (HtmlTextWriter)InnerWriter;
            writer.WriteAttribute(name, value, fEncode);
        }
    }
}


 

posted on Tuesday, October 12, 2004 9:11:43 PM UTC  #    Comments [6] Trackback
# Monday, February 23, 2004

One of the small irritants in the ASP.NET framework is there is no built-in mechanism to set the focus of a control directly in code - you have to emit javascript to handle the job for you.

This is no problem, as ASP.NET gives you standard methods that allow you to register client script blocks with a page, but most of the solutions I've seen to this problem so far involve adding code directly to the inherited Page object to do the job.

However, this to me is untidy and as it's a common enough function to want to achieve, it would be nice to have a component you can quickly drop onto your page.

The code that follows does exactly that; once added to your toolbox, you can drop this component onto your ASP.NET design surface. From the properties box, simply set the ControlToFocus property to the control you want to, er, focus.

It works by handling the target controls' PreRender event, and injecting a startup script into the associated Page object. Very, very simple.

using System;
using System.ComponentModel;
using System.Web.UI;

namespace EdCourtenay.Community.WebControls
{
    public class FocusSetter : Component
    {
        private Control focusControl = null;
    
        public FocusSetter()
        {}

        public Control ControlToFocus
        {
            get { return focusControl; }
            set
            {
                if (focusControl != null)
                    focusControl.PreRender -= new EventHandler(FocusControlPreRender);

                focusControl = value;

                if (focusControl != null)
                    focusControl.PreRender += new EventHandler(FocusControlPreRender);
            }
        }

        private void FocusControlPreRender(object sender, EventArgs e)
        {
            Control control = (Control)sender;
            Page page = control.Page;

            if (page != null)
            {
                string script = String.Format("<script type=\"text/javascript\">document.getElementById(\"{0}\").focus();</script>", control.UniqueID);
                page.RegisterStartupScript("focusControl", script);
            }
        }
    }
}

posted on Monday, February 23, 2004 1:28:17 PM UTC  #    Comments [0] Trackback
# Saturday, February 21, 2004

I've been struggling for a few days with an exception that kept on being raised when authoring my own composite ASP.NET Web Controls:

The format of the file 'VSUserControlHost.dll' is invalid

After spending some time banging my head against a brick wall, it turns out that the cause was the otherwise excellent CodeSmith plugin for VS.NET, which I use to produce things like type-safe collections; disabling it removes the problem immediately.

posted on Saturday, February 21, 2004 9:13:35 AM UTC  #    Comments [0] Trackback
# Wednesday, April 10, 2002

For those of you who don't remember, there used to be a handheld electronic game made by Tiger Electronics, called LightsOut. I got bored travelling up to London on the train the other day, so I whipped out my laptop and started coding this little bit of fun. I came back to it a couple of days ago, and added the original 50 levels from the handheld unit.

lightsOutHandheld.jpg

Please remember that the whole thing was an elaborate attempt to waste time on the spectacularly dull Yeovil to London journey, so don't expect anything truly amazing. But its plus points are that: it's written in C#, it's got 50 really irritating levels and it demonstrates writing your own owner-drawn user controls. Full source code is in the Zip file.

Oh yeah, and if you haven't got it already, you'll need the .NET Framework to run it. Any questions?

posted on Wednesday, April 10, 2002 4:00:10 PM UTC  #    Comments [0] Trackback
# Wednesday, February 06, 2002

I've started work on a port of the classic Repton 3 for the BBC Micro - a game that took up far too much of my time when I was younger - to the .NET platform.

repton_001.png

Considering the amount of time I've had to get the project underway (not a lot) and my unfamiliarity with the .NET framework (there's just so much in there...) I'm quite impressed with how far things have progressed.

I started by having a look at the KRepton port, and I've quite unashamedly nicked all the maps and graphics that were supplied with that version! The only difference is that I've converted all the sprite files to PNG as opposed to BMP. As the .NET framework can handle .PNG files natively, and also as I'm injecting all the images and maps into the final executable, it makes sense. At present, with all 21 map sets and related image files, the whole thing is weighing in at 300k.

repton_002.png

At the moment, I've got the basics of the game in working order. Rocks fall correctly, keys open strongboxes, blips fly around the maze following the left hand wall switching cages into diamonds (albeit far too fast at the moment) and the main character is fully animated.

However, there's quite a lot left to do: as yet there's no scoring mechanism, there's no way to complete a level (crowns, bombs and timers don't work at present), monsters are not implemented, eggs don't crack and falling rocks don't kill you. Phew.

Anyway, as soon as there is a slightly more complete version, I'll post it to this site. You've been warned!

posted on Wednesday, February 06, 2002 4:57:07 PM UTC  #    Comments [0] Trackback