Monday, November 26, 2007

C# unit testing helper

As I am writing some unit tests for a C# application I found myself filling the attributes of the objects with meaningful values. With objects having 26 attributes this can be a very frustrating task and especially if you have to do it twice because you want to test the "add" and the "update" method. The other problem that I had was that I need to compare the values of all attributes of two "user" objects which again is a long task with many attributes. I decided therefore to take advantage of Reflection and letting the computer to do this nasty work.

Possible Solution:
I created a class called "TestHelper" which contains static methods that do exactly this work for me :-). One method fills the public, non inherited properties with random values; except for properties which name ends in "id" and properties which name is "pk". This behaviour is adjusted to my needs but can easyily be changed. The other method takes two objects as input and compares each value of their properties if the objects are of the same type; it returns true if the two objects are "equal". For the compare operations I took some code from Steve Lautenschlager (his code can be found here) and Jonas John (his code can be found here). I needed to mix this two versions because in Johns "RandomHelper" there was missing a method to generate random DateTime objects. The random fill method fills the properties according to their type as follows:
  • DateTime: it puts a random date between now and 3000-01-01
  • String: it puts the name of the property plus a random string of uppercase letters of lenght 50
  • Int, long, Int32, Int64: if they are not ids or pks a random number between 0 and 999999 is set
  • Bool: a random boolean value is created
This behaviour can be easily changed to match your specific needs!

The compare method has some small disadvantage when working with DateTime objects and databases. My problem was that if in the database there was only Time datatype and it was then stored inside a DateTime object it has differed in the last 5 or 6 numbers of the Ticks number. This forced me to make this additional check but it can easily be removed and adopted to other needs.

Here is the code of the TestHelper and the RandomHelper classes:
public class TestHelper
/* This method can be used to fill all public properties of an object with random values depending on their type.
CAUTION: it does not fill attributes that end with 'ID' or attributes which are called 'pk'. They have to be filled manually.*/
public static object FillAttributesWithRandomValues(object obj)
Type type = obj.GetType();
PropertyInfo[] infos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

foreach (PropertyInfo info in infos)
Type infoType = info.PropertyType;
if (infoType.Equals(typeof(DateTime)))
info.SetValue(obj, RandomHelper.RandomDateTime(DateTime.Now, new DateTime(3000, 01, 01)), null);
else if (infoType.Equals(typeof(String)))
info.SetValue(obj, info.Name + " " + RandomHelper.RandomString(50, false), null);
else if ((infoType.Equals(typeof(long)) || infoType.Equals(typeof(Int32)) || infoType.Equals(typeof(Int64)) || infoType.Equals(typeof(int))) && !info.Name.ToLower().EndsWith("id") && !info.Name.ToLower().Equals("pk"))
info.SetValue(obj, RandomHelper.RandomNumber(0, 999999), null);
else if (infoType.Equals(typeof(bool)))
info.SetValue(obj, RandomHelper.RandomBool(), null);
else if (infoType.Equals(typeof(Color)))
info.SetValue(obj, RandomHelper.RandomColor(), null);
return obj;

/* This method takes as input two objects and compares the properties of them.
It returns true if all the public properties of the objects (not inherited ones) are equal.*/
public static bool CompareObjectAttributes(object firstObject, object secondObject)
Type t1 = firstObject.GetType();
Type t2 = secondObject.GetType();
/*the two objects must have the same type*/
if (!t1.Equals(t2)) return false;

PropertyInfo[] infos1 =
t1.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
PropertyInfo[] infos2 =
t2.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
for (int i = 0; i < infos1.Length; i++)
/*this if is needed because if it is a datetime it should compare only the date and the time and not the ticks*/
if (infos1[i].PropertyType.Equals(typeof(DateTime)))
DateTime firstDate = (DateTime)infos1[i].GetValue(firstObject, null);
DateTime secondDate = (DateTime)infos2[i].GetValue(secondObject, null);
/*if the datatype in the database was date then only compare the date part of the datetime object*/
if (firstDate.ToString().Contains("00:00:00") || secondDate.ToString().Contains("00:00:00"))
if (!firstDate.Date.ToString().Equals(secondDate.Date.ToString())) return false;
/*otherwise compare the string representation of the two datetime objects because the ticks may differ*/
if (!firstDate.ToString().Equals(secondDate.ToString()))
return false;
/*if one property value differs return false*/
if (!(infos1[i].GetValue(firstObject, null)).Equals(infos2[i].GetValue(secondObject, null)))
return false;

/*when everything went fine the objects have the same values for their properties*/
return true;

/* Helper class for generating random values*/
public static class RandomHelper
private static Random randomSeed = new Random();

/* Generates a random string with the given length*/
public static string RandomString(int size, bool lowerCase)
/* StringBuilder is faster than using strings (+=)*/
StringBuilder RandStr = new StringBuilder(size);

/* Ascii start position (65 = A / 97 = a)*/
int Start = (lowerCase) ? 97 : 65;

/* Add random chars*/
for (int i = 0; i < size; i++)
RandStr.Append((char)(26 * randomSeed.NextDouble() + Start));

return RandStr.ToString();

/* Returns a random number.*/
public static int RandomNumber(int Minimal, int Maximal)
return randomSeed.Next(Minimal, Maximal);

/* Returns a random boolean value*/
public static bool RandomBool()
return (randomSeed.NextDouble() > 0.5);

/* Returns a random color*/
public static System.Drawing.Color RandomColor()
return System.Drawing.Color.FromArgb(

/* Returns DateTime in the range [min, max)*/
public static DateTime RandomDateTime(DateTime min, DateTime max)
if (max <= min)
string message = "Max must be greater than min.";
throw new ArgumentException(message);
long minTicks = min.Ticks;
long maxTicks = max.Ticks;
double rn = (Convert.ToDouble(maxTicks)
- Convert.ToDouble(minTicks)) * randomSeed.NextDouble()
+ Convert.ToDouble(minTicks);
return new DateTime(Convert.ToInt64(rn));

This is some very simple code on how to use the UnitTestHelper. It is a very simple Console application. To use it in your unit tests adapt it to Your needs since the creation of Unit Tests is not the topic of this post.
class Program
static void Main(string[] args)
Person person = new Person();

Console.WriteLine("Object with random values:");
Console.WriteLine(string.Format("name = {0}", person.Name));
Console.WriteLine(string.Format("age = {0}", person.Age));
Console.WriteLine(string.Format("tshirtcolor = {0}", person.TShirtColor));
Console.WriteLine(string.Format("birthdate = {0}", person.BirthDate));

Person p1 = new Person
Name = "John",
Age = 30,
BirthDate = new DateTime(2000, 10, 19),
TShirtColor = Color.Blue

Person p2 = new Person
Name = "John",
Age = 30,
BirthDate = new DateTime(2000, 10, 19),
TShirtColor = Color.Blue

Person p3 = new Person
Name = "Obama",
Age = 30,
BirthDate = new DateTime(2000, 10, 19),
TShirtColor = Color.Blue

Console.WriteLine("\nPerson 1 equals Person 2 = " + TestHelper.CompareObjectAttributes(p1, p2));
Console.WriteLine("\nPerson 2 equals Person 3 = " + TestHelper.CompareObjectAttributes(p2, p3));

This prints out the following (note that the values may differ on your machine since it are random values):
Object with random values:
age = 32895
tshirtcolor = Color [A=255, R=32, G=148, B=35]
birthdate = 17.07.2065 15:52:02

Person 1 equals Person 2 = True

Person 2 equals Person 3 = False

Friday, November 23, 2007

Team Viewer

See also my new post about Team Viewer!
As I am frequently asked by kith and kin for helping them with their computer "problems" I was since a long time looking for a good tool to resolve such small software problems over the internet. First I thought that maybe ThighVNC might be the solution but the problem there was that it is difficult or impossible to establish a connection through firewalls and routers (maybe there is a way but I was not able to do it). A day when I surfed around I found this tool which aims to "give your desktop wings". I read some comments about the programm and almost everywhere people said that this tool is the simplest remote desktop tool available and, the most important thing, it works through firewalls and routers. The best news is that there is a free version available which according to a member of TeamViewer does not lack any feature compared to commercial versions.

About the usage:
Both parties have to install the software. The application provides for this an invitation e-mail which can be sent to the other person with the download link for the tool. After the successful installation both have to start the tool and the person who sits in front of the computer which is going to be remotely controlled tells the other person the ID and the password. The person who is going to access the desktop of the other computer enters the provided data and a secure connection is established. After that you can work with the other computer as if you were sitting in front of it.
Another possibility is to install the tool as a windows service and use a predefined password which basically "eliminates" the need of someone sitting in front of the remote computer. For the ID I noticed during my tests that it is always the same for a computer so this is no problem.
TeamViewer provides additionally a chat which unfortunately has a small bug. Every time when you are typing and the other person sends you a message the cursor of the chat is set to the first position and if you don't see it you write there. This is not very handy and this bug is already known to the TeamViewer crew and will be fixed soon. Additionally it provides a tool to send files and folders but I did not try it out.

I can only suggest this tool for people who need frequently to help other persons with computer problems or also for other purposes requiring a remote access to a computer. As the TeamViewer crew told me there are no time limitations for the usage of the tool.

Related links:
TeamViewer Homepage

Thursday, November 22, 2007

Set ComboBox value member

The problem was to have assign and later read the value member of a combo box. Because this can be useful to store the primary key or id of the related object in order to get it fast.

UPDATE: see also my latest post which deals with this issue!

Possible Solution1:
To assign these values a data source is needed which can be a list of any type. To make it simpler and useful I created a class which holds the value to display and the value of the value
public class ComboBoxItem
private string display;
private long value;

public ComboBoxItem(string display, string value)
this.display = display;
this.value = value;

public string Display
set { display = value; }
get { return display; }

public long Value
set { value = value; }
get { return value; }

And here some sample code for the usage of the new class:
ComboBox cb = new ComboBox();
List<ComboBoxItem> items = new List<ComboBoxItem>();
items.Add(new ComboBoxItem("item 1", myObject.ID));
items.Add(new ComboBoxItem("item 2", myObject2.ID));
cb.ValueMember = "Value";
cb.DisplayMember = "Display";
cb.DataSource = items;

Note: I read on a forum that they "complained" that I am not using a generic List; but I am using a generic list, I only forgot to convert the "<" and ">" to be displayed correctly :-)

This line selects the combo box item of myObject2 and shows the appropriate display member:
cb.SelectedValue = myObject2.ID;

This line gets the ID of the selected item:
long selectedItemID = cb.SelectedValue;

And you can retrieve the whole combo box item to do whatever you want:
ComboBoxItem cbi = (ComboBoxItem) cb.SelectedItem;
string selectedItemText = cbi.Display;
long selectedItemID = cbi.Value;

When using the data source property it is not possible to add new items to the combo box with the following code:
cb.Items.Add(new ComboBoxItem("new item", 3);

Possible Solution2:
If you do not want to create a class only for the combobox items you can also use the class "DictionaryEntry" in the namespace System.Collections. This gives you the ability to specify different datatypes for the display and value members as shown in the code below:
this.comboBox1.Items.Add(new DictionaryEntry("integer", 5));
this.comboBox1.Items.Add(new DictionaryEntry("string", "i am a string"));
this.comboBox1.Items.Add(new DictionaryEntry("float", 5.6f));
this.comboBox1.Items.Add(new DictionaryEntry("bool", true));
this.comboBox1.Items.Add(new DictionaryEntry("null", null));
this.comboBox1.Items.Add(new DictionaryEntry(1, 1));

this.comboBox1.DisplayMember = "Key";
this.comboBox1.ValueMember = "Value";

this.comboBox1.DataSource = this.comboBox1.Items;

This code populates a combobox with different DictionaryEntry objects. The key can be any object and the value can also be any object. This adds the flexibility of using different display and value members in the same combobox. The last line is needed in order to get the selected value member through the according property of the combobox; because this is only "enabled" if a datasource is set. To retrieve the selected values you can use code like this:
MessageBox.Show(string.Format("key: {0} - value: {1}", ((DictionaryEntry)this.comboBox1.SelectedItem).Key, this.comboBox1.SelectedValue));

If you have only display - value pairs which have all the same datatypes you could use the generic class KeyValuePair which is in the namespace System.Collections.Generic. With this you could populate your combobox like so:
this.comboBox1.Items.Add(new KeyValuePair("customer 1", 1));
this.comboBox1.Items.Add(new KeyValuePair<string, int>("customer 2", 2));
this.comboBox1.Items.Add(new KeyValuePair<string, int>("customer 3", 3));
this.comboBox1.Items.Add(new KeyValuePair<string, int>("customer 4", 4));

this.comboBox1.DisplayMember = "Key";
this.comboBox1.ValueMember = "Value";

this.comboBox1.DataSource = this.comboBox1.Items;

and obtain the selected item like:
MessageBox.Show(string.Format("key: {0} - value: {1}", ((KeyValuePair<string, int>)this.comboBox1.SelectedItem).Key, this.comboBox1.SelectedValue));

The advantage of this is for sure the type safety; because you do not have to cast the key or the value to the correct datatype. The disadvantage of this is that they have all to be of the same key and value type because otherwise the cast when obtaining the selecteditem would throw an exception.
Hope this may help someone :-)

Monday, November 12, 2007

Error during installation of service

The problem:
I tried to create an installer to install a windows service. The two needed installers are the ProcessInstaller and the ServiceInstaller. A requirement was to have a custom Event Log in the system for the service because there are no other ways (as far as I know) to log errors and events of a Windows service. I created therefore a new source and a new log for my application. When I tried then to install the service with "installUtil.exe" I received always an error that the source already exists on the machine and the installation was aborted and rolled back.

The solution:
After some trying I found out, that the ProcessInstaller creates automatically a source in the application log of the computer. As name for the source it uses the name of the project and as I had to realize I used the same name which clearly will produce the error. To solve the issue I created an EventLogInstaller and added it to the list of installers with a different name for the source and another name for the log. This solved all my problems because this installer creates now automatically the log, the source and when deinstalling, everything is removed automatically.
To use the created log the following code can be used:
EventLog.WriteEntry("sourceName", "message");

Saturday, November 3, 2007


In the last post I wrote about Active Record for C#. I would like to mention that from the same supplier there exist also other projects. Among them there is a framework which is called "MonoRail". As far as I understood it makes it possible to develop web applications in a Ruby on Rails like way by having MVC pattern and Action Pack. I think that this could be a big help for the development because it separates the model, the view and the controller which makes the code more readable and change tolerant. Unfortunately I did not have time to try it out, but as soon as I have some I definitely want to try it.

I also found another framework which aims to "help a website to build itself". It is called SubSonic and tries to port the "best" things of Rails to C#. The description sounds very interesting and I definitely would like to give it a try. But the time, the time... :-)

Related Links:
Castle Project Home
MonoRail Home
SubSonic Home

Active Record for C#

As I am a fan of Active Record and in the company in which I work C# is used to develop applications I looked for an Active Record implementation for C#. After some searching I found one which is called Castle Active Record. It does exactly what I want namely it provides a framework which makes it possible to use the Active Record pattern with C#.
As I am curious I tried it out imediatly. I did the tutorial provided on the homepage.
I had no problems with the tutorial and initially I tried it with a PostgreSQL database and I was not able to get it work. I always got an error message when I tried to let Active Record create the database schema. After some researches on the internet and some trying out I found out that I had to add a reference for the two files "Npgsql.dll" and "Mono.Security.dll" which are located at "C:\program files\PostgreSQL\8.2\Npgsql\", to my Visual Studio project. After that everything worked fine.
To make it work with MySQL you simply have to download and install the MySQL Connector from here. After you installed it you simply add it to your references and everything should work.

The project showed me how Active Record can be used with C# and I think that it can be very useful also for commercial projects. Give it a try...

I realized that the demo project is only available as VS2003 version. I will make it available as VS2005 version as soon as possible for people who have not time to write the project from scratch ;-) In my version I additionally added a search functionality which automatically iterates over all attributes of an object by using reflection and allows therfore searching in all attributes/columns.


Useful links:
Castle Active Record Home
MySQL Home
PostgreSQL Home

ReadOnly controls

I had the problem, that I needed controls which can be set to ReadOnly in Visual Studio. Since I have not found a solution in the internet that fits my needs I decided to create my own controls and I would like to make them available to other persons who may need them. The controls where created with Visual Studio 2005 Express and the .NET Framework 2.0.

To make the controls even more customizable they provide in additon to the "ReadOnly" property two other properties:
  • ReadOnlyBackColor - specifies the back color of the control when it is in ReadOnly state.
  • ReadOnlyForeColor - specifies the fore color of the control when it is in ReadOnly state.
In the screenshots below you can see the impact of this properties. Only for the Checkbox the ReadOnlyBackColor is not available, because this color can be changed with the BackColor property.


To use the controls in your project simply drag and drop the dll file of the controls into your Visual Studio Toolbox.

Here some screenshots:

To download the source code of the demo form and the dll file see the following link:

Ruby on Rails

As internship project for my thesis of applied computer science I developed a web application with Ruby on Rails. Since that point I am a big fan of Ruby on Rails and the used concepts such as Active Record, MVC, database migrations, scaffolds, unit- and function testing and many more. If you find some time I would stronlgy suggest to give it a try because it makes web development fast, easy and agile. "Simple" web pages can be created in a very small amount of time; but Rails provides also features for complex pages. This requires some time of vocational adjustment but then it is almost fun to create dynamic web pages.

Active Record
The most impressing thing of Rails was the built in support for the Active Record pattern. This is the short definition of what it is:
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
Martin Fowler
The idea behind is very very interesting. It mainly states that you take care of building the model with its objects and the relations between them and Active Record maps then automatically to an underlying database management system. The big advantages of this are that you can change the database when you like because you are not bounded to a specific DBMS; another big advantage is that you do not have to write any SQL which reduces errors and safes you a lot of code and maybe also a class which is called DBManager ;-).
To start you simply "tell" Active Record which is the database that you use, the name of the catalog and the user with which to connect to the DBMS. After that you create so called migration scripts which are written in Ruby and are used to create the needed tables in the database; you can also create the database tables manually or with SQL but I found that this was the easiest way. After the successful creation of the tables you can start coding. It is very simple to do that as you can see by this example:

This code creates a new user and stores it in the database:
user = = "uname"
user.passwor = "mypassword"

This code updates an existing user and stores the changes in the database:
user = User.find(3) = "newName"

This code destroys a user:
user = User.find(3)

It is as simple as this and you do not have to write any SQL statements.

Finally some usefull links to get started with Ruby on Rails:
Ruby on Rails Home
One click Ruby installer
Tutorial (not tried by myself)

Hello world!

Hello out there. I decided to start a Blog where I post my opinions and ideas.

Since I work in a small software company in south tirol I think that I will face with problems during development and I would like to post here possible solutions that I/we found which may be useful also for other people...