Friday, August 18, 2006

Visual Studio.NET 2003 Service Pack 1 Released

Service pack 1 for Visual Studio .NET 2003 is finally out! It has fixes for more then 400 issues. (feel a lot better about my own code now, lol)
Check it out

Thursday, August 10, 2006

Weijie on Wheels

Haven't had any time to do any Ruby on Rails lately. Instead I've spend most of my spare time on Wheels. Yay, We finally got our car last Thursday and since then I've put 1000km on it. Gas prices are high these days but we couldn't resist the convenience and mobility it brings. We've been in New Brunswick for a long time but we just realized how beautiful it is, so we plan to travel within New Brunswick for the rest of the summer.
Here are some scenes from our road trip

Wednesday, August 09, 2006

Find and FindAll in generic collections

In .NET 2.0, searching through generic collections such as Arrays and Lists are easier with the new Find and FindAll methods. Both methods accepts a Predicate parameter, which is a delegate to a method. According to MSDN, these methods run in O(n). In situations like searching for item(s) in a collection, I used to write utility functions with simple bubble sort algorithm. This causes code duplication and O(n^2) is just too slow.

Therefore, I wrote couple of test cases to explore these two new methods. Check it out!
TestFixtureSetUp

[TestFixture]
public class TestFindInICollection
{
private List _numbers;
private const int TOTAL_NUMBER = 20;
private const int MAX = 100;
private DomainModel[] _models;

[TestFixtureSetUp]
public void TestFixtureSetUp()
{
_numbers = new List();
_models = new DomainModel[TOTAL_NUMBER];

Random r = new Random();
Console.WriteLine("Orignal Collection");
Console.WriteLine("Size = " + TOTAL_NUMBER);

//populate the number list with pseudo-random numbers
//populate the model list
for (int i = 0; i < TOTAL_NUMBER; i++)
{
int radNum = r.Next(MAX);
_numbers.Add(radNum);
Console.WriteLine(radNum);
_models[i] = new DomainModel(i, DateTime.Now.ToLongTimeString());
}
}

...


Find numbers smaller then 50 using anonymous delegate

[Test]
public void CanFindAllNumbersUsingAnonymousMethod()
{
//_number is prepopulated with 20 random numbers from 0 to 50
//find numbers smaller then 50
List smallerPartition = _numbers.FindAll(delegate(int testInt) { return testInt < 50; });
Console.WriteLine("Numbers smaller then 50");
Console.WriteLine("Size = " + smallerPartition.Count);

foreach (int n in smallerPartition)
{
Assert.IsTrue(n < 50);
Console.WriteLine(n);
}
}


Find the domain model with id equals to 10

[Test]
public void CanFindModelUsingAnonymousMethod()
{
int id = 10;
DomainModel model = Array.Find(_models, delegate(DomainModel testModel) { return testModel.Id == id; });
Assert.AreEqual(10, model.Id);
Console.WriteLine(model);
}


Find numbers larger then 50 by calling a helper function that returns a Predicate

[Test]
public void CanFindAllNumbersUsingFunction()
{
//find numbers bigger then 50
List biggerPartition = _numbers.FindAll(BiggerThen(50));
Console.WriteLine("Numbers bigger then 50");
Console.WriteLine("Size = " + biggerPartition.Count);

foreach (int n in biggerPartition)
{
Assert.IsTrue(n > 50);
Console.WriteLine(n);
}
}

private Predicate BiggerThen(int p)
{
return delegate(int testInt) { return testInt > p; };
}


Simple DomainModel Class

class DomainModel
{
private int _id;
private string _label;

public DomainModel(int id, string label)
{
_id = id;
_label = label;
}

public int Id
{
get { return _id; }
set { _id = value; }
}


public string Label
{
get { return _label; }
set { _label = value; }
}

public override string ToString()
{
return _id + " " + _label;
}
}

AgileCoder:Operating-Systems

Wednesday, July 12, 2006

Fixing Firefox Flash Video Sound problem on Ubuntu Dapper

I've been using Ubuntu Linux as my main OS at home. After upgrading to Ubuntu Dapper recently, Firefox refuses to play flash video sound from time to time. After some googling I found two methods to solve this problem.

Method 1

sudo ln -s /usr/lib/libesd.so.0 /usr/lib/libesd.so.1
sudo mkdir -p /tmp/.esd/
sudo touch /tmp/.esd/socket


Method 2

sudo aptitude install alsa-oss
sudo gedit /etc/firefox/firefoxrc

FIREFOX_DSP=”aoss”

TechWorks:Software-Engineering

Tuesday, June 27, 2006

Using CruiseControl.NET with MSBuild

Introduction

Originated from Extreme programming, the concept of Continuous Integration has been gradually adopted to other traditional software development methodologies. I think it will bring tremendous value to our .NET based projects so I decided to set up the environment and give it a try.

CruiseControl.NET is one of the most commonly used Continuous Integration tools on the .NET platform. It works well with NAnt to build Visual Studio 2003 based projects, but as of NAnt 0.85-rc 4 there is no support for <solution> task for Visual Studio 2005 projects. As a result, NAnt can only compile Visual Studio 2005 solution on a per project basis. By default, unlike VS 2003, Visual Studio 2005 uses a new file structure based Web project, which doesn't have a project file. This imposes even more problems for NAnt to work with VS 2005 solutions.

Setting up CruiseControl.NET and NAnt to work with Visual Studio 2003 projects is relatively easy, so I will try to set up CruiseControl.NET to work with Visual Studio 2005 projects here. Since Visual Studio 2005 and .NET Framework 2.0, Microsoft introduced a new extensible, XML-based build engine named MSBuild. In fact, the solution files and project files in VS 2005 are all written in MSBuild format. So instead of using NAnt with CruiseControl.NET, we are able to leverage MSBuild for compiling VS 2005 based solutions.

Prepare to install

First make sure the project compiles with MSBuild, by checking out a fresh copy and navigate to the project root directory then issue "msbuild MyProject.sln"

Install CruiseControl.NET

Installing CruiseControl.NET is easy. Simple grab the installer from CruiseControl.NET at Thoughtworks. I also downloaded and installed CCTray. CCTray is used to view and control the build process from client side, it can be installed locally on the build server as well as remotely.

The approach

In this approach, I use CruiseControl.NET to run NAnt scripts which in turn use MSBuild for compiling the Visual Studio 2005 solution. MSBuild is more capable then just compiling, but I am more familiar with NAnt so it's easier for me to setup NAnt the way I wanted. Basically I use NAnt script to clean up directory, get source code, and call MSBuild executable to compile. I am sure CruiseControl.NET can employ MSBuild directly and MSBuild is able to do things like cleaning up the directory and getting the source code. But I won't get to that until I actually have time to learn MSBuild.

Files that will be edited/created are as follows:
  • NAnt.exe.config - NAnt config file (located in the NAnt bin directory)
  • ccnet.config - CruiseControl.NET config file (located in the CruiseControl.NET installation directory)
  • cruise.build - NAnt build script (new file created in "C:\ProjectBuild\CruiseControl.NET\server
    \MyProject\WorkingDirectory")

Configure CruiseControl.NET
Add settings to ccnet.config file, add project section as follows

<project>
<name>MyProject</name>
<webURL>http://localhost/ccnet/
default.aspx?_action_ViewProjectReport=true&
server=local&project=MyProject
</webURL>
<triggers>

<intervalTrigger seconds="600" />

</triggers>

<sourcecontrol type="vss">

<project>$/MyProjectRoot/MyProject</project>

<username>MyUserName</username>

<password>MyPassword</password>

<ssdir>\\server\vss</ssdir>

</sourcecontrol>

<tasks>

<nant>
<executable>C:\ProjectBuild\nant-0.85-rc3\bin\nant.exe</executable>
<baseDirectory>C:\ProjectBuild CruiseControl.NET\server\MyProject\WorkingDirectory
</baseDirectory>
<buildFile>cruise.build</buildFile>
<targetList>
<target>run</target>
</targetList>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
</nant>

</tasks>
</project>


As aforementioned the configuration didn't use MSBuild directly, rather it relies on NAnt to define the build tasks.

Configure NAnt

NAnt config file
MSBuild does not come with a XML Logger by default, so I need to use an external logger to get this functionality. I download the dll from here. And then I move the ThoughtWorks.CruiseControl.MsBuild.dll file to "C:\ProjectBuild\CruiseControl.NET\Tools".

Add MSBuild property to properties section
NAnt.exe.config

<properties>
<!--properties defined here are accessible to all build files -->
<property name="msbuild.exe"
value="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe" overwrite="false" />
<property name="msbuild.logger.class"
value="ThoughtWorks.CruiseControl.MsBuild.XmlLogger" overwrite="false" />
<property name="msbuild.logger.assembly"
value="C:\ProjectBuild\CruiseControl.NET Tools\ThoughtWorks.CruiseControl.MsBuild.dll" overwrite="false" />
</properties>


NAnt build file
Finally, this is my NAnt build file
cruise.build

<?xml version="1.0" ?>
<target name="clean">

<delete dir="Source" failonerror="false" />

<mkdir dir="Source" />

</target>

<target name="get" depends="clean">

<vssget username="MyUserName"

password="MyPassword"

localpath="Source"

recursive="true"

replace="true"

writable="false"

dbpath="\\server\vss\srcsafe.ini"

path="$/MyProjectRoot/MyProject"/>

</target>

<target name="build" depends="get">
<exec program="${msbuild.exe}">

<arg value="/logger:${msbuild.logger.class},${msbuild.logger.assembly}" />

<arg value="/target:Build" />

<arg value="/verbosity:minimal" />

<arg value="/noconsolelogger" />

<arg value="C:\ProjectBuild\CruiseControl.NET\server\MHI WorkingDirectory\Source\MyProject.sln" />

</exec>
</target>

<target name="run" depends="build">

</target>

<project default="build">

</project>

References

Monday, June 26, 2006

Sharepoint 2007 comes with Blogs, Wikis and RSS

The up-coming Sharepoint 2007 will come with features found in most Portal/Content Management sites. Check out the video on Channel9 Sharepoint 2007 -- Blogs, Wikis, RSS
TechWorks:Software-Engineering

Thursday, June 22, 2006

Reading the Applying Domain-Driven Design and Patterns book

I am half way through reading the Applying Domain-Driven Design and Patterns book written by Jimmy Nilsson.I have always wondered how do domain-driven design, test-driven development and O/R mapper play together. Eric Evans's Domain-Driven Design: Tackling Complexity in the Heart of Software got me started on Domain-driven development. The book talked a lot about the different theories behind domain-driven development and the importance of ubiquitous language but it lacked concrete example. As a newbie to domain-driven development, I was very much in need for some concrete examples.

The Applying Domain-Driven Design and Patterns book serves as an excellent complement to Eric's book. I like author's pragmatic style. The author understands the nature of software very well so he doesn't try to establish a "standard" way of solving a problem but rather providing several solutions with their pros and cons enumerated. Therefore, I will be able to choose the best solution that fits the problem. Unfortunately, the book doesn't come with any source code and the NWorkspace framework mentioned by the author is no where found on the Internet.
TechWorks:Software-Engineering

Use del.icio.us for categories in blogger

I have successfully intergarted the del.icio.us category function to my blog, as you can see from the side bar to the right. Many thanks to John for his nice tutorial 3 ways to use del.icio.us for categories in blogger. As a Firefox user, I followed the third approach which uses the Greasemonkey extension with Greasemonkey script written by Johan Sundström.
TechWorks:Software-Engineering