# Thursday, February 25, 2010

I've been developing iPhone apps for the past 9 months using the recommended development tools, being Xcode, Interface Builder and the iPhone SDK.

Being a C# .NET programmer didn't make this easy: Objective-C is... weird and... primitive. Dealing with pointers after 10 years of focusing on problems instead of memory addresses is a slight culture shock, but luckily having previous C and C++ experience helps a lot.

In September last year, the geniuses (by lack of a stronger word) at Novell's Mono team came up with MonoTouch, a C# cross-compiler that allows you to build iPhone apps using .NET and C#, including the use of most of the .NET Framework. I'm not going to go into detail on how this works. Enough has been written about this subject.

One feature of MonoTouch caught my attention: as of version 1.2, an ADO.NET provider was added for accessing the iPhone's native SQLite database format. A relational database accessed from C# code desperately needs an ORM, don't you agree? So last weekend I decided to try and port the CoolStorage ORM to MonoTouch. It wasn't as easy as I thought, because of some severe limitations in the version of SQLite installed on the iPhone, but in the end I got it working, and working well.

To give you an idea of the time you'll save by using an ORM like CoolStorage on the iPhone, I will present three examples:

  1. Reading a list of records using the iPhones's SQLite library (C / Objective-C)
  2. Reading a list of records using ADO.NET + MonoTouch
  3. Reading a list of records using CoolStorage + MonoTouch

We're not going to make it too complicated. The example reads a list of customer records. It retrieves the ID, Name and City. No filters are being applied, simply a list of customers ordered by Name. After that, it prints the records to the console.

The examples also omits the declaration of the Customer class (which is used to hold a single customer record)

Native Objective-C example:

NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];

databasePath = [documentsDir stringByAppendingPathComponent:@"mydb.db3"];

sqlite3 *database;

customers = [[NSMutableArray alloc] init];

if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
   const char *sql = "select id,name,city from customer order by name";
   sqlite3_stmt *stmt;
   
   if(sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) == SQLITE_OK) {

      while(sqlite3_step(stmt) == SQLITE_ROW) {
           Customer *customer = [[Customer alloc] init];
	   
           customer.CustomerID = sqlite3_column_int(stmt, 0)];
           customer.Name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 1)];
           customer.City = [NSString stringWithUTF8String:(char *)sqlite3_column_text(stmt, 2)];

           [customers addObject:customer];
           
	   [customer release];
      }
   }

   sqlite3_finalize(stmt);
}

sqlite3_close(database);

for (int i=0;i<[customers count];i++) {
   Customer *customer = [customers objectAtIndex:i];

   NSLog("ID: %d, Name: %@, City: %@",customer.CustomerID,customer.Name,customer.City);
}

It's pretty obvious that things will get unbearably complicated when you try to do things like accessing related records, persisting data to the database, and so on.

Now let's introduce MonoTouch and ADO.NET.

ADO.NET example (MonoTouch):

string dbName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "mydb.db3");

var conn = new SqliteConnection("Data Source=" + dbName);

List customers = new List();

using (var cmd = conn.CreateCommand())
{
  conn.Open();
  cmd.CommandText ="select id,name,city from customer order by name";
  using(var reader = cmd.ExecuteReader())
  {
    while (reader.Read())
    {
      Customer customer = new Customer();

      customer.CustomerID = int.Parse(reader["id"].ToString());
      customer.Name = (string) reader["name"];
      customer.City = (string) reader["city"];

      customers.Add(customer);
    }
  }
}

foreach (var customer in customers)
   Console.WriteLine("ID: {0}, Name: {1}, City: {2}",customer.CustomerID,customer.Name,customer.City);

Now that's a lot better, don't you think? But still, it requires a lot of boilerplate code that's just there to distract you from what you're actually trying to do: read a list of records from the database.

So let's move to the next level:

CoolStorage example (MonoTouch):

string dbName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "mydb.db3");

CSConfig.SetDB(dbName, false);

var customers = Customer.List().OrderedBy("Name");

foreach (var customer in customers)
   Console.WriteLine("ID: {0}, Name: {1}, City: {2}",customer.CustomerID,customer.Name,customer.City);

Well, you get the picture... Now you can focus on the application instead of data access technology. Isn't this what it's all about?

In case you want to use this in your own code, go ahead and grab the latest development build of CoolStorage, which now fully supports MonoTouch. It can be downloaded from the CoolStorage website. Best of all, it's open source...

kick it on DotNetKicks.com
Thursday, February 25, 2010 9:23:24 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [1] -
 |  | 
# Friday, November 28, 2008

We all love unit tests (do we?). Yes we do (repeat 100 times). And we all love mocking for making life easier, but sometimes we just want to write some simple unit tests that don't require any mocking at all, because the code you are testing is easy to test without having to resort to all those mocking tricks

But what if you need to test code that relies on the date or some elapsed time? Let's say you wrote a simple caching class that automatically removes items from the cache when a certain amount of time has passed since the last access. It's tempting to slap some Thread.Sleep() calls in there to trigger expiration of cache items, but that will slow down your unit test, and most importantly, it's not accurate. What if you want to test some edge cases? Like, what happens when you access an item at the exact timeout period?

A few years ago I worked with a brilliant Java architect who simply said: "just mock the time!". What he meant was that I should create a fake DateTime class which behaves like the real DateTime class with one important difference: YOU control the time, not the system clock.

How is that done?

Simply create an interface with a single getter property of type DateTime:

public interface ITimeProvider 
{
   DateTime Now { get; }
}

Then you create 2 classes that implement this interface: one that returns the real time, and one that can be used to control a "fake" time:

public class RealTimeProvider : ITimeProvider
{
    public DateTime Now { get { return DateTime.Now; } }
}

public class MockTimeProvider : ITimeProvider
{
    private DateTime _time;

    public DateTime Now { get { return _time; } set { _time = value; } }
}

Of course the class(es) you want to test should be aware of this. For example, our cache class could look like this:

public class Cache
{
     private ITimeProvider _time = new RealTimeProvider();

     public ITimeProvider TimeProvider { get { return _time; } set { _time = value; } }

     // ... the rest of the class implementation
}

In our class implementation, all calls to DateTime.Now should be replaced by TimeProvider.Now.

And now the fun part, faking the time in our unit tests:

[Test]
public void TestCacheTimeout()
{
    ITimeProvider time = new MockTimeProvider();
    Cache cache = new Cache();

    cache.TimeProvider = time; // Tell our cache class to use our fake time

    cache.Add("A" , 1); // add an item to the cache

    Assert.IsTrue(cache.Contains("A")); // check if it's added

    time.Now += TimeSpan.FromHours(1); // let one hour go by...

    Assert.IsFalse(cache.Contains("A")); // check if it was automatically removed
}

That's pretty cool and simple, isn't it? Wouldn't it be nice if we could do the same in real life? ;-)

Next week I'll talk a little about unit testing multithreaded concurrency issues...

kick it on DotNetKicks.com
Friday, November 28, 2008 6:41:29 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
 |  |  | 
# Wednesday, October 29, 2008

Most people believe dogfooding is the perfect way of ensuring the quality of the software you're creating. I couldn't agree more.

The only problem is that when you use your own software, you always have the feeling that it's not quite "done". There's always something that you can do better, always something that can be improved, always some features that you feel would be nice.

Especially when building a framework this can become a real problem because you never feel done. Another problem is making sure your framework maintains backwards compatibility with previous releases.

Well, I just mentioned this because I finally decided to freeze version 2.0 of ProMesh.NET and get it ready for release. Release candidate 3 has just been published on CodePlex

Thoughts on open source frameworks

A few weeks ago, a fellow developer asked me why I chose to make my projects open-source. That was a pretty good question because when you look at it: compared to just building a framework for your own use, it makes life more complicated: you have to write documentation, support users, and more headaches.

I didn't have to think long before I could answer that question: releasing a custom framework as open source forces you to be disciplined about your code and documentation. After all, you can't afford to write code you are ashamed of, can you? If you write software for your own use, you tend to write code that... well... sucks.

And of course, let's not forget the whole point of open source software: letting other developers contribute. It creates a dynamic that you would never get when you're just building and using your own little framework

If all of the above sounds like a bunch of crap, it's probably because I'm not a native English speaker, or ... it is just crap

kick it on DotNetKicks.com
Wednesday, October 29, 2008 10:32:35 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [1] -
 |  | 
# Friday, March 07, 2008

Every decent programming book tells you to write readable code. Few people do.

Code is read a lot more often than it is being written. Fact.

Programming style is all about personal taste. Agreed.

On the other hand, well... let's just take a very small piece of code from the BCL written by Microsoft:


    Type p = this;
    if (p == c) 
        return false; 
    while (p != null) {
        if (p == c) 
            return true;
        p = p.BaseType;
    }
    return false; 


Without changing any of the code (except spacing and indentation):


    Type p = this;
    
    if (p == c) 
        return false; 
    
    while (p != null) 
    {
        if (p == c) 
            return true;
        
        p = p.BaseType;
    }
    
    return false; 


I know the code is longer, and there are better examples to be found, but what makes code readable is being able to see the structure of the source code. This can be accomplished by using correct spacing, empty lines and correct placement of braces.

I especially want to stress the importance of using empty lines. Their primary purpose is to visually separate blocks of code. Note the example above. The original code has no empty lines whatsoever, which makes code very hard to read (even if you wrote the code yourself).

When should you use empty lines (IMHO) :

  • Before and after every control block ("if", "for", "while")
  • Before and after return statements
  • After blocks of variable declarations
  • After blocks of assignments
  • In between assignments if they "don't belong together"
  • (a curly brace counts as an empty line of course)

This is a small code fragment which illustrates some of these points:


    newSetMethod = typeBuilder.DefineMethod( /*ommitted*/ );

    ILGenerator ilGen = newSetMethod.GetILGenerator();

    ilGen.Emit(OpCodes.Ldarg_0);
    ilGen.Emit(OpCodes.Ldstr , baseProperty.Name);
    ilGen.Emit(OpCodes.Ldarg_1);

    if (baseProperty.PropertyType.IsValueType)
    {
        ilGen.Emit(OpCodes.Box,baseProperty.PropertyType);
    }

    ilGen.EmitCall(OpCodes.Call,setFieldMethod,null);

    ilGen.Emit(OpCodes.Ret);


Of course, there's more to readability than inserting empty lines, but it's a point which is often neglected. The most often heard excuse is that it makes code shorter. (sigh)

I don't want to start a religious war, just trying to express a (strong) opinion.

kick it on DotNetKicks.com
Friday, March 07, 2008 9:04:43 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [16] -
 |  | 
# Wednesday, March 05, 2008

Constructing related .NET objects (an "object graph") from XML files is a familiar challenge to most developers out there. Although it is not hard to write something like that: just read the tokens and fill the appropriate objects.

In most cases, the code produced is not very readable and hard to maintain, because the problem is usually implemented in a linear fashion with lots of loops and repeated (or similar) statements.

When faced with this problem, I usually use the "Factory Method" pattern to implement this. The idea is that every object class has its own FromXml() method which creates its own object according to the XML node passed in as a parameter.

For example, let's suppose we want to create a customer object from an XML segment where the customer name is a child element and the customer ID is an attirbute like:

<Customer id="CUST1"><Name>My Customer Name</Name></Customer>


The factory method would look like this (I'm using C# syntax for object construction):

public partial class Customer
    {
        public static Customer FromXml(XmlNode xmlNode)
        {
            Customer customer = new Customer {
                                        Id = xmlNode.Attributes["id"].Value,
                                        Name = xmlNode["Name"].InnerText,
                                        Orders = new List<Order>()
                                    };

            return customer;
        }
    }

 
Now suppose each customer has a number of orders, which are located under the <Orders/> child element. So we use the Order object's factory method to create the Order object from the XML child nodes:

public partial class Customer
    {
        public static Customer FromXml(XmlNode xmlNode)
        {
            Customer customer = new Customer {
                                        Id = xmlNode.Attributes["id"].Value,
                                        Name = xmlNode["Name"].InnerText,
                                        Orders = new List<Order>()
                                    };

            foreach (XmlNode xmlOrder in xmlNode.SelectNodes("Orders/Order"))
                customer.Orders.Add(Order.FromXml(xmlOrder, customer));

            return customer;
        }
    }
    


Got the picture? Now let's pull it all together, and parse the following XML file to our object graph containing "Customers", "Orders" and "OrderItems":

<?xml version="1.0"?>
<CustomerList>
<Customer id="CUST1">
  <Name>Mr X</Name>
  <Orders>
   <Order number="5001">
    <OrderItems>
     <OrderItem>
      <Description>Item 1</Description>
      <Price>45.00</Price>
     </OrderItem>
     <OrderItem>
      <Description>Item 2</Description>
      <Price>99.00</Price>
     </OrderItem>
    </OrderItems>
   </Order>
   <Order number="5002">
    <OrderItems>
     <OrderItem>
      <Description>Item 3</Description>
      <Price>120.00</Price>
     </OrderItem>
    </OrderItems>
   </Order>
  </Orders>
</Customer>
<Customer id="CUST2">
  <Name>John Doe</Name>
  <Orders>
   <Order number="5003">
    <OrderItems>
     <OrderItem>
      <Description>Item 4</Description>
      <Price>550.00</Price>
     </OrderItem>
     <OrderItem>
      <Description>Item 5</Description>
      <Price>41.50</Price>
     </OrderItem>
    </OrderItems>
   </Order>
  </Orders> </Customer> </CustomerList>


And the code:

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.Load("test.xml");

CustomerList customerList = CustomerList.FromXml(xmlDoc.DocumentElement);

public partial class CustomerList : List<Customer>
{
}

public partial class Customer 
{
    public string Id { get; private set; }
    public string Name { get; set; }
    public List<Order> Orders { get; private set; }
}

public partial class Order
{
    public int OrderNumber { get; private set; }
    public List<OrderItem> OrderItems { get; private set; }
    public Customer Customer { get; set; }
}

public partial class OrderItem
{
    public string Description { get; set; }
    public decimal Price { get; set; }
    public Order Order { get; set; }
}

public partial class CustomerList
{
    public static CustomerList FromXml(XmlNode xmlNode)
    {
        CustomerList list = new CustomerList();

        foreach (XmlNode xmlCustomer in xmlNode.SelectNodes("Customer"))
            list.Add(Customer.FromXml(xmlCustomer));

        return list;
    }
}

public partial class Customer
{
    public static Customer FromXml(XmlNode xmlNode)
    {
        Customer customer = new Customer {
                                    Id = xmlNode.Attributes["id"].Value,
                                    Name = xmlNode["Name"].InnerText,
                                    Orders = new List<Order>()
                                };

        foreach (XmlNode xmlOrder in xmlNode.SelectNodes("Orders/Order"))
            customer.Orders.Add(Order.FromXml(xmlOrder, customer));

        return customer;
    }
}

public partial class Order
{
    public static Order FromXml(XmlNode xmlNode, Customer customer)
    {
        Order order = new Order {
                            OrderNumber = Int32.Parse(xmlNode.Attributes["number"].Value),
                            Customer = customer,
                            OrderItems = new List<OrderItem>()
                        };

        foreach (XmlNode xmlItem in xmlNode.SelectNodes("OrderItems/OrderItem"))
            order.OrderItems.Add(OrderItem.FromXml(xmlItem, order));

        return order;
    }
}

public partial class OrderItem
{
    public static OrderItem FromXml(XmlNode xmlNode, Order order)
    {
        return new OrderItem {
                                 Description = xmlNode["Description"].InnerText,
                                 Price = Decimal.Parse(xmlNode["Price"].InnerText),
                                 Order = order
                             };
    }
}


The advantages of using this pattern are obvious:

  • Very readable (and maintainable) code
  • The implementation details on how to read a particular type of object are located in the class itself, making it very easy to make a small change (for example adding a new property to an object)
  • Easy to read recursive object graphs
  • Properties that should be read-only can be made read-only (no messing with "internal" properties)

Note that a similar pattern can be used for writing objects to an XML file. Just create a member method "ToXml()".

kick it on DotNetKicks.com
Wednesday, March 05, 2008 9:03:02 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [4] -
 |  | 
# 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] -
 | 
# 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] -

# 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

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] -
 |  | 
# Tuesday, July 31, 2007

There seems to be quite a bit of demand for a preview of ProMesh.NET, my MVC-type Web Application Framework for .NET 2.0. To satisfy this demand I decided to publish a small demo application (with source code) on CodePlex, which includes the current compiled ProMesh.NET assemblies

The demo application contains a web project and a unit testing project. The web application shows the following features:

  • Mapping of client variables to method parameters (even url parameters mapped to objects)
  • The template rendering engine
  • Form handling and validation (very basic in this application)
  • Typed session properties
  • Application configuration

The unit tests included in the example contain 2 tests:

  • Checking if access to unauthorized pages is properly blocked
  • Login procedure of a registered user

I expect the first public release (including source code) to be released sometime on wednesday or thursday.

Direct link to the download page on CodePlex: Click here

Update: In the meantime, the first beta has been published.

kick it on DotNetKicks.com
Tuesday, July 31, 2007 9:50:18 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [12] -
 |  | 
# Thursday, July 26, 2007

These days, every blogging developer seems to have a list of tools and libraries they are using on a daily basis. In many cases those posts were pretty useful to me, as I got to know a few tools I didn’t know.

So, here’s my list…

Development tools

Libraries / Frameworks

kick it on DotNetKicks.com
Thursday, July 26, 2007 11:32:32 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2] -
 | 
# Wednesday, July 25, 2007

Yesterday, an old article resurfaced on dotnetkicks.com about validating Guid strings. Several comments hinted at the possibility of letting the .NET Framework convert it to a Guid and catching the FormatException.

WTF !?

I must be very old-fashioned, because I am still very religious about (mis)using exceptions in normal application flow. Exceptions were designed for exceptional events, not for validating user input.

Even Microsoft picked up on that, because they added a bunch of TryParse() methods in version 2.0 of the .NET Framework.

In case you’re wondering if there are any REAL reasons for avoiding exceptions in the normal flow of an application, I’ll give you two:

  1. Exceptions are slow. Let me repeat: SLOW.
  2. When you are in a debugging sessions, and you told the debugger to break at the first exception (which is often done), you will know what I’m talking about.

 

kick it on DotNetKicks.com
Wednesday, July 25, 2007 8:31:38 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
 |  | 
# Tuesday, July 17, 2007
Ever wanted to get a list of all types (classes) that inherit from a specific base class or implement a specific interface? If the answer is yes, read on, because it is actually very simple.

In .NET, if you want to check if a type is a base class or interface for a given type, you simply call the method IsAssignableFrom() on the base type or interface. To get get all types satisfying this criteria, simply look at all the types in all assemblies...
public static List<Type> FindCompatibleTypes(Type baseType)
{
   List<Type> types = new List<Type>();

   foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
   {
      foreach (Type type in assembly.GetTypes())
      {
         if (type != baseType && baseType.IsAssignableFrom(type))
            types.Add(type);
      }
   }

   return types;
}
I told you it was simple :-)
kick it on DotNetKicks.com
Tuesday, July 17, 2007 8:50:48 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -

# Sunday, July 15, 2007
Let me first give you some background information:

Number formats are different in different parts of the world. North Americans use the "." to separate the decimal part of a number. Europeans use ",". The "thousand separator" is the other way around.
The .NET framework will automatically select the correct notation depending on your geographic location, but this is where it all goes wrong for Europeans (and sometimes even for non-Europeans).

First of all, many websites are targeted at the whole world, so they run into trouble when people are required to enter a number with a fraction part.
Another problem is that in the beginning of the personal computer age, there was no such thing as "regional settings", so computer users grew accustomed to entering a "." for decimal numbers. And old habits die hard, so European software developers are in trouble.

So I decided to allow both forms of input in all my applications. This makes everybody happy and causes less frustration (and support headaches for me).

In .NET, you implement this with a simple call to the Parse() or TryParse() method:
double.TryParse(stringValue.Replace(',', '.'), NumberStyles.Any, 
NumberFormatInfo.InvariantInfo,
out doubleValue)
double.Parse(stringValue.Replace(',', '.'), NumberStyles.Any, NumberFormatInfo.InvariantInfo)

There is one slight drawback: users are not allowed to enter thousand separators, but I have never encountered anyone doing this.

kick it on DotNetKicks.com
Sunday, July 15, 2007 2:01:49 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1] -

# Saturday, July 14, 2007
We all know the Convert.ChangeType() for changing a value from one (unknown) type to another (unknown) type at runtime, but this method doesn't handle nullables and enums very well.

What may seem a simple task isn't that simple after all. You have to differentiate nullables, value types and enums. I threw in a little recursion, and I came up with this:
public static object ConvertType(object value, Type targetType)
{
if (value == null)
return null;

if (value.GetType() == targetType)
return value;

if (targetType.IsValueType)
{
if (!targetType.IsGenericType)
{
if (targetType.IsEnum)
return Enum.ToObject(targetType, value);
else return Convert.ChangeType(value, targetType);
}

if (targetType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
Type realType = targetType.GetGenericArguments()[0];

return ConvertType(value, realType);
}
}

return Convert.ChangeType(value,targetType);
}

This method will do all conversions correctly, but it will return null if you pass null for a value type. This can be fixed with an extra if() check, but I thought it wasn't necessary.



The best use for this method is for converting values read from a database to a variable that is compatible with the database type, but not exactly the same.
kick it on DotNetKicks.com
Saturday, July 14, 2007 10:59:34 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1] -

# Friday, July 06, 2007
Without going into specifics, ProMesh.NET is a web application framework based on the ASP.NET HTTP "Pipeline".

Key points about the framework:
  • Avoids the ASP.NET page model, so no ASP.NET web controls
  • Links directly into IIS using Http Handlers and Http Modules
  • Template-based system with master templates and content templates. Very powerful built-in or runtime server-generated macros can be embedded in the templates.
  • Templates can be created using off-the-shelve HTML editors like Dreamweaver and Microsoft Web Expression
  • Full control of the rendering process
  • Integrated with CoolStorage.NET
  • Built-in logging and statistics
  • ...
The project will probably be released as open source at CodePlex.

This framework has been used for internal projects for several years, including some high traffic sites like www.autosport.be and www.cartoonbase.com, so stability and performance have been proven. Now it's time to release it in the open...

kick it on DotNetKicks.com
Friday, July 06, 2007 10:35:52 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3] -
 |  |  | 
# Thursday, July 05, 2007
I am often asked the question "Can't I just RUN my Windows Service without installing and starting it?".

My answer usually is "No, you can't but..."

There is a "but": you can create your Windows service as a hybrid application, so it will run as a console application also.

Why would you want to do that?
  • It makes debugging from within Visual Studio a breeze
  • Sometimes you want to show some debugging information in a production environment by using Console.WriteLine()
  • You don't always want to install your service to see if it runs in a particular environment
Turning a .NET Windows service into a hybrid application is actually very simple. In your Main() method you add the following:
static class Program
{
static void Main(params string[] parameters)
{
if (parameters.Length > 0 && parameters[0].ToLower() == "/console")
new MyService().RunConsole(parameters);
else ServiceBase.Run(new ServiceBase[] { new MyService() });
}
}
Then, in your service class, add a RunConsole() method:

   public void RunConsole(string[] args)
{
OnStart(args);

Console.WriteLine("Service running... Press any key to stop");

Console.Read();

OnStop();
 }

That's all there is to it. To run your service as a console app, just specify "/console" as the first paramter when running the .EXE.

UPDATE: all of this, and more is now all wrapped in a .NET library (open-source) named Vici WinService.

kick it on DotNetKicks.com
Thursday, July 05, 2007 1:40:15 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [4] -

# Sunday, July 01, 2007
I just added support for SQLite 3 to CoolStorage.NET (my object mapping library). I used the open source System.Data.SQLite ADO.NET provider which seems a pretty solid product.

Adding support for this "lite" database was pretty straightforward.

The only problem I had was with quoted identifiers: identifiers can be quoted using double quotes, but they behave a bit strange. For example, if you want to quote the identifiers in this query:

SELECT c.CustomerID, c.Name from tblCustomer c

you would write:

SELECT "c.CustomerID", "c.Name" from "tblCustomer" c

This doesn't work. You get the following result set:

c.CustomerIDc.Name
c.CustomerIDc.Name
c.CustomerIDc.Name
c.CustomerIDc.Name
c.CustomerIDc.Name


To fix this, you need to change it to this:

SELECT "c"."CustomerID", "c"."Name" from "tblCustomer" c

Other than that, I'm pretty impressed (so far)

Technorati Profile

kick it on DotNetKicks.com
Sunday, July 01, 2007 8:20:52 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
 | 
# Tuesday, June 26, 2007
Nothing really, if you use it for simple personal projects. Once you start building web applications that are a bit more complex, you start running into all kinds of problems.

What kind of problems am I talking about?
  • Building web sites in multiple languages is a major pain in the butt. Once you have 2 or more languages to support, and a few hundred pages, maintaining the resource files is hell. Especially when you are using a version management system (as you should) and have people dedicated to translating stuff.
  • The event model Microsoft magically weaved in ASP.NET is not suited for web applications. HTTP wasn't meant for a user interface framework based on events. Period.
  • Performance of the ASP.NET page rendering system is extremely slow. There are caching techniques, but these are hard to use and even harder to maintain.
  • ViewState ! Anyone who has done some serious work using ASP.NET will know exactly what I'm talking about.
  • Building standards-based websites (using CSS) is extremely hard (there are CSS "adapters" available, but they are hardly easy to use)
  • The Microsoft Ajax framework is a monster (both in size and usability)
When building web applications, I only use the first steps in the ASP.NET pipeline: Http Handlers and Http Modules. Page rendering is done using a multi-language template engine combined with a logging framework for page/session/visitor/cookie tracking.

Of course, when you don't use the ASP.NET page model, you have to know a little bit about HTTP and HTML/CSS, but I wouldn't call this a bad thing. Many web developers these days know nothing about "low level" web technology, meaning they get into trouble when something "special" or "low-level" needs to be done. I prefer to have control over the whole process: gets, posts, urls, parameters, form variables, etc.

A presentation of the framework I built will follow in my next post.

kick it on DotNetKicks.com
Tuesday, June 26, 2007 8:20:07 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1] -
 |