# Wednesday, August 29, 2007

Let me just say that I am pretty impressed by what Miguel De Icaza and the other Mono guys have accomplished by creating Mono.

I have never been impressed by Linux and I am not surprised by the slower than expected adoption of the operating system, despite huge efforts by Novell and Red Hat. To me, the main reason is the lack of standardization in the different distributions. Setting up and configuring a Linux system is never the same. Different vendors use different front-ends (Gnome vs KDE), the file systems are organized differently, boot procedures are totally different, ...

But, I have always been intrigued by Mono, the .NET platform for Linux which is "sponsored" by Novell. Mono has always been pretty up-to-date by implementing new .NET stuff and compiler features as soon as (or sometimes even sooner than) Microsoft made them publicly available

I was a little curious to see how ProMesh.NET (MVC Web Framework for .NET 2.0) would run on Mono (if at all), so I did the following:

  • Download the VMWare image with a pre-installed Mono installation on SUSE Linux 10.2
  • Download VMPlayer (free)
  • Copied the latest ProMesh.NET source tree to the virtual machine
  • Fired up MonoDevelop
  • Compiled the framework... Works (well, it compiled)
  • Copied the ProMesh.NET demo application to the virtual machine
  • Compiled the demo app... Works!
  • Started xsp2.exe (the lightweight .NET web server for Mono)
  • Opened the index.ashx page using FireFox: WORKS
  • Went through the complete demo site. Everything worked!

I was utterly amazed by the painless process of compiling and running a ProMesh.NET application on Mono, something I've never tried before (I did have some previous experience with MonoDevelop, but not a lot).

This is pretty exciting stuff, knowing you can just grab your ProMesh.NET web application, dump it on a Linux box and run it from a Linux web server.

Mono team: good job!!

kick it on DotNetKicks.com
Wednesday, August 29, 2007 9:20:10 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2] -
 |  |  |  | 
# Wednesday, August 22, 2007

This article may be extremely obvious to many people, but I am sure a lot of C# developers will be surprised by what will follow.

What's the difference between

MyType myObject1 = (MyType) anotherObject;

and:

MyType myObject2 = anotherObject as MyType;

Well, when "anotherObject" is assignable to MyType, both lines of code do the exact same thing, but when "anotherObject" is not of the correct type, the assignment to "myObject1" will throw an exception, but the second line of code will run fine and "myObject2" will be null.

Surprised? I was too, but it's in the C# specs.

FYI, the type cast is compiled to the "castclass" IL instruction, while the "as" version is compiled to the "isinst" instruction. Two different beasts

kick it on DotNetKicks.com
Wednesday, August 22, 2007 10:08:53 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [10] -
 | 
# Monday, August 20, 2007

What's worse than:

  • Global variables?
  • Badly chosen variable names?
  • ASP.NET WebForms :)?
  • Leaky abstractions?
  • ... enter your worst coding nightmare ...

I've got one word for you:

Dependency Injection (well, that's two words actually)

Why?

Remember 20 years ago? All of a sudden, WYSIWYG word processors were all the rage. For a good reason. WHAT YOU SEE IS WHAT YOU GET. Exactly!. Writing, editing, reading a document while you don't have to worry about what the end result will look like. It was heaven.

The same is true for writing and reading code. Code should (more or less) do what it looks like it is doing. That's obvious.

What does Dependency Injection do with your code? Nobody but the guy who implemented it knows. Now, THAT's comforting.

You read a piece of code, and you think you understand what it's doing, but the actual code is something completely different at runtime. WYSINWYG. A maintenace nightmare.

I know a lot of people will disagree, but all this code-changing magic is an accident waiting to happen. I wonder if this stuff is used in the Space Shuttle program code.

But that's just MHO.

kick it on DotNetKicks.com
Monday, August 20, 2007 7:56:47 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [4] -
 | 
# Sunday, August 12, 2007

In my previous article I talked about the hunt for a good JSON parser/serializer. For my current project I only needed a serializer to generate JSON from any .NET object, so for now it’s a bit overkill to use a full blown JSON library.

After looking at the specs for JSON, I figured it couldn’t be too hard to write a JSON serializer in C#. Not only was it not that hard, it was very short too: about 100 lines of code (well, 110 without the empty lines).

The serializer can handle any regular data type, including DateTime (for which there is no standard in JSON).

Here it is: (feel free to use it for anything you like)

 

public class JSONSerializer
{
    private readonly StringBuilder _output = new StringBuilder();

    public static string ToJSON(object obj)
    {
        return new JSONSerializer().ConvertToJSON(obj);
    }

    private string ConvertToJSON(object obj)
    {
        WriteValue(obj);

        return _output.ToString();
    }

    private void WriteValue(object obj)
    {
        if (obj == null)
            _output.Append("null");
        else if (obj is sbyte || obj is byte || obj is short || obj is ushort || obj is int || obj is uint || obj is long || obj is ulong || obj is decimal || obj is double || obj is float)
            _output.Append(Convert.ToString(obj,NumberFormatInfo.InvariantInfo));
        else if (obj is bool)
            _output.Append(obj.ToString().ToLower());
        else if (obj is char || obj is Enum || obj is Guid)
            WriteString("" + obj);
        else if (obj is DateTime)
            _output.Append("new Date(" + ((DateTime)obj - new DateTime(1970,1,1)).TotalMilliseconds.ToString("0") + ")");
        else if (obj is string)
            WriteString((string)obj);
        else if (obj is IDictionary)
            WriteDictionary((IDictionary)obj);
        else if (obj is Array || obj is IList || obj is ICollection)
            WriteArray((IEnumerable)obj);
        else
            WriteObject(obj);
    }

    private void WriteObject(object obj)
    {
        _output.Append("{ ");

        bool pendingSeparator = false;

        foreach (FieldInfo field in obj.GetType().GetFields(BindingFlags.Public|BindingFlags.Instance))
        {
            if (pendingSeparator)
                _output.Append(" , ");

            WritePair(field.Name, field.GetValue(obj));

            pendingSeparator = true;
        }

        foreach (PropertyInfo property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (!property.CanRead)
                continue;

            if (pendingSeparator)
                _output.Append(" , ");

            WritePair(property.Name,property.GetValue(obj, null));

            pendingSeparator = true;
        }

        _output.Append(" }");
    }

    private void WritePair(string name, object value)
    {
        WriteString(name);

        _output.Append(" : ");

        WriteValue(value);
    }

    private void WriteArray(IEnumerable array)
    {
        _output.Append("[ ");

        bool pendingSeperator = false;

        foreach (object obj in array)
        {
            if (pendingSeperator)
                _output.Append(',');

            WriteValue(obj);

            pendingSeperator = true;
        }

        _output.Append(" ]");
    }

    private void WriteDictionary(IDictionary dic)
    {
        _output.Append("{ ");

        bool pendingSeparator = false;

        foreach (DictionaryEntry entry in dic)
        {
            if (pendingSeparator)
                _output.Append(" , ");

            WritePair(entry.Key.ToString(),entry.Value);

            pendingSeparator = true;
        }

        _output.Append(" }");
    }

    private void WriteString(string s)
    {
        _output.Append('\"');

        foreach (char c in s)
        {
            switch (c)
            {
                case '\t': _output.Append("\\t"); break;
                case '\r': _output.Append("\\r"); break;
                case '\n': _output.Append("\\n"); break;
                case '"': 
                case '\\': _output.Append("\\" + c); break;
                default:
                    {
                        if (c >= ' ' && c < 128)
                            _output.Append(c);
                        else
                            _output.Append("\\u" + ((int) c).ToString("X4"));
                    }
                    break;
            }
        }

        _output.Append('\"');
    }
}
kick it on DotNetKicks.com
Sunday, August 12, 2007 9:30:00 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [13] -

I’ve been using AjaxPro for a few years now, and I must say that I have been very happy with it. It was even integrated with ProMesh.NET, meaning you just had to call RegisterTypeForAjaxPro() and the method stubs were being generated in the HTML output.

I was in the process of checking out some JavaScript frameworks, when I came across jQuery. Pretty cool stuff, although not that much different from Mootools, which I have been using for a few months. The Ajax stuff in jQuery is pretty easy to use and started playing around with it until… Hmm, I am moving away from the point of this article.

Anyway, not that all of this matters, but I started thinking about how hard it would be to offer the same functionality that AjaxPro offered, all integrated in the ProMesh.NET framework.
Calling the server methods was a no-brainer, because the framework already supports calling specific methods on Controller objects. The “hard” part was returning objects to the client as  JSON strings. I didn’t feel like writing my own JSON generator, so I started checking out some open-source stuff.

I found the following products:

All of these did exactly what I needed, so it was hard to choose. What was very unusual, is that one of these products, LitJSON, had a public domain license (i.e. no license at all). Not that the licensing for the other offerings was too restrictive to be included in ProMesh.NET, the thought of not having to worry at all about licensing made me decide to take a better look at LitJSON. The product seems to be very solid and well written, so I added it to the source tree of ProMesh.NET. I will include it with the 1.1.0 release of ProMesh.NET, but with a notice in the release notes that the JSON stuff hasn’t been tested as thoroughly as it should have been.

So, to make a long story short: ProMesh.NET now supports native Ajax method calls using jQuery or another JavaScript framework. Currently, only the jQuery JavaScript provider has been included in the latest build, but you can plug in any provider you like (using the IAjaxProvider interface).

kick it on DotNetKicks.com
Sunday, August 12, 2007 1:52:42 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3] -

# Wednesday, August 08, 2007

Scott Bellware wrote an interesting article “Monorail vs. Rails Isn't a Meaningful Question” which touches the subject of choosing a technology for building web applications.

The question “if you're building web apps on .NET, what leads you to assume that you should be building on .NET?” came up twice in his post. While this is a question a technologist might ask, it is a no-brainer for the stake-holders.

Think about this: As a stake-holder, why would you use Ruby (on Rails) when it is at least 100 times harder to find Ruby developers than it is to find good .NET developers? You wouldn’t. Even if I was a die-hard Ruby enthusiast, and I needed to build a “real” web application my company depended on, I would never pick Ruby on Rails.

So obviously .NET is a safe choice, but that doesn’t necessarily mean you should use the ASP.NET framework. There are other (better?) frameworks available for building web applications in .NET (I even doubt that the Microsoft website is using ASP.NET Web Forms for all its content). It’s not that hard to teach a .NET developer how to use MonoRail or ProMesh.NET or (…), but it is a lot harder to make a C# developer use Ruby (on Rails).

Ruby may be the better technology for web apps, .NET seems (for now) to be a better (business) choice for real web applications.

kick it on DotNetKicks.com
Wednesday, August 08, 2007 12:47:31 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [17] -
 |  |  | 
# Monday, August 06, 2007

A few days ago I activated “MyBrand” on FeedBurner, which allows you to use your own domain name instead of “feeds.feedburner.com”. I chose to use “feeds.activa.be”, and indeed, this worked as advertised. (I had to change some DNS settings, but that was a no-brainer)

To my surprise, I saw this on my FeedBurner stats page under “Uncommon Uses”.

Feedburner_uncommon

WTF??

It seems FeedBurner treats my “MyBrand” URL “http://feeds.activa.be/activa” as an “uncommon use”

Why my original RSS feed is also there is another mistery to me…

kick it on DotNetKicks.com
Monday, August 06, 2007 10:35:20 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1] -

One of the most powerful features in .NET is the ability to use reflection to do all kinds of neat stuff at runtime, like

  • Find out what properties, fields, methods, etc. are in a class
  • Create objects without knowing their type at compile time
  • Call methods by name (even private ones)
  • Check attributes on classes, methods, fields, …

The web framework I built over the last few years, ProMesh.NET, relies on reflection for a lot of the features it offers. Often though, I am asked if the heave use of reflection doesn’t have a significant impact on performance.

My answer usually is: YES, but it doesn’t matter. Now you probably think that I don’t care about performance or that I’ve had too much too drink. None of the above. I’ll explain:

In ProMesh.NET, there’s a feature that allows you to just declare session properties in your class that will be constructed at runtime, like this:

   private SessionProperty<string> _mySessionVar1;
or
   private SessionProperty<string> _mySessionVar2 = new SessionProperty<string>();

You don’t have to initialize _mySessionVar1. The framework uses reflection to construct the object.

Creating _mySessionVar1 is about 20 times slower than creating _mySessionVar2. Shocking? Yes. Unacceptable? No!

The reason why it is not unacceptable is that it takes 2.2 µs (microseconds) to create _mySessionVar1, and 0.12 µs (microseconds) to create _mySessionVar2. These figures include dynamically iterating the over the class members, determining their type and looking up the appropriate constructor. This is the simplified code which creates the fields at runtime:

foreach (MemberInfo member in GetType().GetMembers())
{
if (member is FieldInfo)
{
FieldInfo field = (FieldInfo) member;

ConstructorInfo constructor =
field.FieldType.GetConstructor(Type.EmptyTypes);

field.SetValue(this, constructor.Invoke(new object[0]));
}
}

Considering this happens when a web page is requested, which usually involves some database access, a little disk access and some other time-consuming stuff, a complete web page request takes between 50ms and 2000ms. Assuming we have 20 session variables to construct at runtime, the overhead is … between 0.08% (worst case) and 0.002%.

So, yes it is MUCH slower, but it doesn’t matter. (not for applications of this kind)

kick it on DotNetKicks.com
Monday, August 06, 2007 8:48:01 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3] -
 |  |  |  |  | 
# Wednesday, August 01, 2007

The other day I was checking out the Microsoft Web Client Software Factory, but I wasn’t very impressed. Too complicated, too “heavy”, too …

Anyway, I did stumble upon something interesting: it includes a class that allows you to define a class member that will survive page requests (in other words, it is stored in the session). Of course, the class can’t be used without implementing the whole framework. Too bad. But then I thought: hey, this shouldn’t be too hard to implement as a standalone class… and it isn’t. Fifty lines of code to be precise (and it takes the concept a little further than the original)

Imagine you are writing a web application, and imagine you could have a (typed) property in your class that, whenever you access it, you are actually writing to the session? Not too hard, but it requires some code:

public int CustomerID
{
   get
   {
      if (HttpContext.Current.Session["CustomerID"] == null)
         return -1;
      else
	 return (int) HttpContext.Current.Session["CustomerID"];
   }
   set
   {
      HttpContext.Current.Session["CustomerID"] = value;
   }
}

Not too bad, I know, but we can do better

How about this:

private SessionProperty<int> _customerID = new SessionProperty<int>("CustomerID",-1);

public int CustomerID
{
   get { return _customerID.Value; }
   set { _customerID.Value; }
}

The number of lines of code isn't that much lower, but it is a lot cleaner.

You can even do this:

private SessionProperty<Customer> _customer 
   = new SessionProperty<Customer>("CurrentCustomer",
                              delegate { return new Customer() });

public Customer CurrentCustomer
{
   get { return _customer.Value; }
   set { _customer.Value; }
}

In the example above, if there is nothing in the session when you first access the property, it will create a new instance of the Customer and store it in the session. No more fear for NullReferenceExceptions. Isn’t this cool?

Did I forget something? ... Yes! The code!

    
public delegate T Creator<T>();

public class SessionProperty<T>
{
private readonly string _sessionKey;
private readonly T _defaultValue;
private readonly Creator<T> _defaultValueCreator;

public SessionProperty(string sessionKey)
{
    _sessionKey = sessionKey;
    _defaultValue = default(T);
}

public SessionProperty(string sessionKey, T defaultValue)
{
    _sessionKey = sessionKey;
    _defaultValue = defaultValue;
}

public SessionProperty(string sessionKey, Creator<T> defaultValueCreator)
{
    _sessionKey = sessionKey;
    _defaultValueCreator = defaultValueCreator;
}

public T Value
{
    get
    {
	if (ProMeshHttpContext.Current.Session[_sessionKey] == null)
	{
	    if (_defaultValueCreator != null)
	    {
		T value = _defaultValueCreator();

		Value = value;

		return value;
	    }
	    else
		return _defaultValue;
	}
	else
	    return (T) HttpContext.Current.Session[_sessionKey];
    }
    set
    {
	HttpContext.Current.Session[_sessionKey] = value;
    }
}
kick it on DotNetKicks.com
Wednesday, August 01, 2007 9:27:36 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3] -
 |  |