February 2006 - Posts
Last week
Alex Thissen and I competed in the
RAD Race 2006. We arrived Thursday at 7 in the morning to setup our computers, and we got the assignment at 8. From then it was full speed until 6 in the evening. Again at Friday we started at 8 in the morning, and went full stop at 3 in the afternoon. Then the jury came to see what modules everyone had completed. And it wasn’t as much as they expected.
Normally in the RAD Race, the second day is for change requests. You get a new set of modules which may be completely new functionality, but also changes on modules you (might have) already completed. But the organizers probably underestimated the complexity of the assignment, because none of the teams were up for the change requests. This resulted in another day to work on the same assignment, and even than no one completed the assignment fully.
Assignment
The assignment was to create an application to create workshops, seminars and conferences. Visitors should be able to register for these events. All three were different in a way, which made it really complex. Conferences could span multiple days and have multiple (parallel) sessions per day, where a workshop could span multiple days, but could only be registered as a whole by visitors. Additional requirements were multiple webservices for credit card registration, management functionality for editing employees, users, assigning hotels and speakers to events, and more.
Everyone of course worked really hard for two days, and many teams had all different kinds of problems. One team implemented a large module, to see it crash in the end because they hadn’t tested it anymore. Another team had some problems with their framework. A lot of teams overlooked minor requirements in the specifications, or just didn’t implement parts because of the complexity.
One of our problems was that we completely focused on WinForms, where about 80% of the assignment was web-based, which made us decide to go completely for a web application. We could’ve had setup a complete website with user registration and all, which is something we’ll definitely do if we’ll compete next year. ;-)
Tools
The tools we’ve used are Visual Studio 2005 and of course Microsoft .NET 2.0 and ASP.NET 2.0. For our database we’ve used SQL-Server 2005 and for generation of our datalayer we’ve used
LLBLGen Pro. I’m very pleased with LLBLGen Pro, as for our RAD experience, it was great. Creating an eventcollection, adding a filter and tell it to retrieve the data worked really fast. Optionally adding filters, paths through other tables to retrieve those as well, etc, etc. Two thumbs up in my experience. Perhaps later I'll add another post how LLBLGen Pro turned out to work in a 'real' application using a distributed scenario, which I'm currently working on.
Conclusion
Alex and I both think we didn’t do that bad, but it’s really hard to tell what team really stood out of the rest, or who completed most modules. The assignment was very complex and the jury will have a hard time, I guess.
At the end of next month, we’ll have to see who has finally won, at the
Database Systems event, where the winner will be announced. The experience was great though. We have no idea how we performed, compared to the other teams, but we already know next year we’ll do a lot better, as we’ve really learned a lot about Rapid Application Development.
I asked my colleague and our ASP.NET expert Alex Thissen how I could solve a problem I had for some time. I have a Windows Form application and a ASMX 2.0 project in the same solution. Whenever I start the debugger to step through some code, I have to attach the debugger to the webserver that's running my webservice. This can be quite annoying, when you have to do this dozens of times a day. Alex had the solution, and was surprised I didn't know this already. Fact is however, I asked a lot of people about this in the last few days, but no one knew the answer. So although I'm not the only one to not know this (until now), you might be as surprised as Alex was. ;-)
The solution is to set both the Windows Forms application as the webservice as a startup project. Right-click your solution and you'll be presented with the following menu.

Now click the highlighted option and you'll be presented with a dialog window. In it, you can setup the multiple startup projects, as shown in the image below.

I've added two green arrows to show you exactly the projects I've set as startup projects. Once you close this dialog window, you'll see the solution is now bold, instead of just one project. Now the debugger will automatically attach itself to both projects. It will also launch the default webbrowser however (of course Internet Explorer) which you'll have to turn off. Go to the project property pages of your webservice, and select the "Start options" in the list on the left. You'll be presented with the following options, of which you'll have to set the "Don't open a page", as shown in the image below.

That's it, happy debugging!
My colleague Anko Duizer has created a rather
extensive list of do's and dont's about SQL-Server. There are some tips in there that are incredibly important, and perhaps he can illuminate some of those in the future. Like why you should avoid the use of GUIDs, you must not prefix stored procedures with ‘sp_’ and more like these.
I’ve recently took a glimpse at a PowerPoint slide-deck by
Rob Howard about the
performance of sites. For all asp.net sites (site, forum, blogs, etc), blogs.msdn.com, dotnetnuke.com and aspinsiders.com, they have only two web servers and one database server running. Rob shows for example, how their physical database server is running on three separate RAID0 configurations, one for OS, one for data and one for logs. The performance gain was incredible once implemented. This is also one of the tips Anko mentions, between the 46 others. Just nice to know how to boost performance of your database server.
Anyway, if you want to know all this yourself, you can start with taking a really deep dive into SQL-Server with Bob Beauchemin. Immediately after DevDays 2006 here in The Netherlands, he’s going to present a class at our Class-A office in Woerden. For more information about the class,
click here.
A while ago I heard a definition on Smart Clients that was said to be from Microsoft. The person who told me the definition, said Smart Clients should be able to work disconnected. I totally disagreed with him, because I think in a lot of circumstances, working disconnected does not add anything to the user experience. Technically it’s a much larger challenge to provide disconnected functionality and when you require a user interface to compare local data against remote (server) data, you have to build many more screens then normal.
I think when your client can connect to a server via (for example) webservices and can also be updated automatically via internet or local intranet, you’ve got a pretty smart client there. Now just a minute ago, I came across a definition of a smart client, via the
MSDN Smart Client site.
“Smart clients are easily deployed and managed client applications that provide an adaptive, responsive and rich interactive experience by leveraging local resources and intelligently connecting to distributed data sources.”
Now that’s a pretty smart definition. Some will probably interpret the “intelligently connecting” as offline capabilities, but for me it’s the connecting intelligently to my server via webservices. Securely, encrypted, reliable and what else you want.
Agreed? Or not?! :-)
Back in the old days, when we all were using Visual Studio.NET 2003, we had this cool tool called CopySourceAsHTML. It was a plugin into Visual Studio with which you can copy source into your wysiwyg editor, so your post will have code-coloring.
Just read that the tool by Colin Coller was retwritten for Visual Studio 2005 by Derick Bailey and Jason Haley has put together an installer for it. Download it here. After installation, in Visual Studio 2005, go to Options, Environment, Addin/Macro security and press the "Add..." button. Then go to the installation folder, confirm, restart Visual Studio, select some code and right-click it.
Happy posting!
In
my previous post, I gave a small introduction into
System.Transactions and the
TransactionScope object. You might already know about it, but I noticed a lot of people still don’t, while they really should. It’s really easy to use and understand, and can solve a lot of problems.
For example, how about using it for your unit tests? While your tests should test small units, it’s also wise to have integration tests, and see if your application is still accessing the database correctly. Common practice is to do this on a daily build server, where you setup the database before you start the test-run.
Another practice is that you cannot assume that your tests run serially. If that was the case, you’d insert a user into some table, and in the second test use that same user. But tests can run parallel or in a different sequence. So it’s wiser to setup some method that will insert a user, and have one test check if that’s working. We’ll call that InsertUserTest. Another test can than use the method to insert a user, and see if it can update that user. We’ll cat this one UpdateUserTest.
When the InsertUserTest breaks, the UpdateUserTest will automatically break also. But you can then track it down pretty fast to the InsertUserTest test, fix that one, and the UpdateUserTest will probably also run.
Now transactions come into scope, because at the end of every test, you want that inserted user to be rolled back. This is done very easily with the TransactionScope object. First, let's look at the InsertUser method. This method must run in our transaction, but the method itself doesn't have to know about it. We don't have to close the connection, because the using statement will take care of it, as it calls the Dispose() method on the SqlConnection.
/// <summary>
/// Inserts a user
/// </summary>
/// <returns>Returns the primary key value</returns>
private int InsertUser()
{
int identityValue = 0;
using (SqlConnection conn = new SqlConnection())
{
conn.Open();
// Insert user, get the primary key value
// for the example, we'll set it here:
identityValue = 1;
}
return identityValue;
}
Next is the insert test, which calls the InsertUser. If the above method throws an exception, or the insert fails, the Assert in this method will also fail. Because the call to InsertUser lies within the TransactionScope block, the inserted user will be rolled back.
[Test]
public void InsertUserTest()
{
int identityValue = -1;
using (TransactionScope scope = new TransactionScope())
{
identityValue = InsertUser();
}
Assert.AreNotEqual(-1, identityValue);
}
The last one is the update test. You can see it also calls the top InsertUser method, but also tries to update the user. Both will fall under the same transaction, and both will be rolled back, because we don't call the scope.Complete() method.
[Test]
public void UpdateUserTest()
{
int identityValue = -1;
int rowsUpdated = 0;
using (TransactionScope scope = new TransactionScope())
{
identityValue = InsertUser();
using (SqlConnection conn = new SqlConnection())
{
conn.Open();
// update user, using the retrieve pk value.
// set rowsUpdated; again, for the example, we'll set it here:
rowsUpdated = 1;
// Do NOT call scope.Complete()
// The transaction will rollback.
}
}
Assert.AreNotEqual(-1, identityValue);
Assert.AreEqual(1, rowsUpdated);
}
This shows how easy it is to unit test your application, without having to worry a bit about the data inserted.
If you're using .NET 2.0 together with SQL-Server 2005, you're in for a treat. The TransactionScope. A lot of people have written about it already, and most people are raving about it. Most, because there seem to be some drawbacks about the new System.Transactions namespace. But before I'll start talking about those, let's hear the good parts first. I'll explain what TransactionScope is, for those who might not yet know, and in another post explain the difficulties you might have with it.
The good part is that we can create a transaction extremely easy, and include complete codeblocks. If you take a look at the codeblock below, you can see that we're including the new System.Transactions namespace. And in the InsertUser method, we're starting a TransactionScope. Everything within the brackets { and } can enlist in the transaction. When something goes wrong, the scope.Complete() is skipped and at the closing of the bracket, the transaction is rolled back.
using System.Transactions;
public void InsertUser(string userName, string password)
{
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection())
{
conn.Open();
// do some saving
scope.Complete();
}
}
}
Everything within the TransactionScope, that's handled by a Resource Manager (RM), will be enlisted in the transaction. In our case it's the connection to SQL-Server 2005. And the transaction manager (TM), is in this case, the Lightweight Transaction Manager (LTM). It's a new TM so your transactions don't need the heavy-weight Microsoft Distributed Tranasction Coordinator (MSDTC). This makes your transactions much lighter and faster. But you need to meet certain criteria before this can be true. If not, you'll still need MSDTC for your transactions. The cool part however is, that your transactions are automatically escalated to the MSDTC, without you knowing. It's all happening in the background. This is called promotable enlistment. And at the same time, that's a bad thing. Because when it happens, and you're not expecting it, your transaction will be much slower.
So when will your transactions be promoted to an MSDTC coordinated transaction? When the transaction spreads multiple app domains, two durable RMs show up in the same transactions, or a durable RM is used that does not support single phase notifications. more
This list is courtesy of Sahil Malik, who inspired me to write this blog entry, and the next few. Inspired, because I don't share his opinion on this subject in every way. Also because I had about 15 explorer windows open searching for the right information, of which 10 were different articles on his weblog. I'll explain what the above list means, in the near future. You might want to check out the TransactionScope class yourself.
As said before, we're using Windows Workflow Foundation (WF) to support flexible processes within our application. Read Marc's blog about our experiences.
Anko Duizer already mentioned WF being quite difficult, and he had doubts about the mainstream developers picking up WF, as Microsoft expects. But I didn't expect it to be so difficult. The fact that we don't have a lot of documentation and even less support, probably influences our judgement on the product. But it's also pretty complex when you consider you need a lot of activities, with underlying activities and even more code-behind with a lot of events. And then we're not even talking about persisting state, getting it back and having completely new architectural issues. Simple things like getting all objects in a certain state raise a lot of questions and/or issues.
And looking through release notes you notice that they've build a lot of things that were requested after beta 1. That might seem nice, but it doesn't give me much confidence that they've build WF based on experience of what's exactly needed in such a product. I think they've still got a long way to go. And as far as I can tell, this should be released together with Vista and Office 12. Pretty hard deadlines for all teams, which in my opinion can only result in pushing the date backwards.