Building an application and/or library usually starts with an OO design. Typically from that design you will define interfaces and implement base classes, which can be used as a starting point for building your application. Defining the signature of a base class is very important. More specific, the visibility (public, protected & private) and purpose (virtual or not) of the methods are very important. Take for example an order-entry form based application that contains several screens for adding and updating data. Every screen will need to implement a kind of save method for persisting the changes. The very basic structure of your design can be: public interface IDataView
{
void Save()
}
public class DataViewBase: IDataView
{
public virtual void Save()
{
}
}
Here the intention is that for example every screen of your application need to inherit from DataViewBase and implement the Save method. The problem with this design, is that the interface is marked as virtual (see Virtuality) and is responsible for two jobs, namely that it is part of an interface and for specifying the implementation.
A better way is to apply the Template Method design pattern, also called the 'Hollywood principle', that is, 'Don't call us, we'll call you'. (This pattern is also used a lot throughout the .NET SDK library.) public class DataViewBase: IDataView
{
public void Save()
{
DoSave();
}
protected virtual void DoSave()
{
}
}
This way you have complete control of the interface and you can easily add some logging before and after the save for example, extra checks, etc. If for example you need to implement whether a form-screen is dirty or not, you can easily plug it in as follow: public class DataViewBase: IDataView
{
public void Save()
{
// do some checks
// do some logging
if (IsDirty())
DoSave();
}
protected virtual void DoSave()
{
}
protected virtual bool IsDirty()
{
return true;
}
}
If for example you need to extend the application such that when the screen is dirty you get a dialog box asking if you want to save or not. You can simply change the Save method without affecting the derived classes public class DataViewBase: IDataView
{
public void Save()
{
// do some checks
// do some logging
if (IsDirty())
if (MessageBox.Show("Do you want to save?", "Information",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question) == DialogResult.Yes)
DoSave();
}
protected virtual void DoSave()
{
}
protected virtual bool IsDirty()
{
return true;
}
}
Due to the fact that the interface and the custom implementation is separated, we can easily extend and have control of the interface. In the other case we would have a lot of code duplication and in most cases we would violate the Liskov Substitution principle.
Here I describe how you can add syntax highlighting (C#, SQL, Javascript, etc.) in MediaWiki. In MediaWiki you can add syntax highlighting through GeSHiHighlight but I found it interesting for combining the world of PHP and .NET. For syntax highlighting in .NET I used the CodeHighlighter ASP.NET Control from Actipro Software.
The intersection between PHP and .NET for communication are web services. Therefore I created a .NET webservice that provides the method Parse with the parameters code and languagekey (= C#, SQL, XMl, etc.) which returns a HTML string.
using System;
using System.Web;
using System.Web.Services;
using System.Text;
using System.Web.Services.Protocols;
using System.Configuration;
using ActiproSoftware.CodeHighlighter;
using ActiproSoftware.SyntaxEditor;
[WebService(Namespace = "http://tempuri.org/SyntaxHighlighting")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SyntaxHighlighting : System.Web.Services.WebService
{
[WebMethod]
public string Parse(string code, string languageKey)
{
if (string.IsNullOrEmpty(code))
return string.Empty;
SyntaxLanguage language = GetSyntaxLanguage(languageKey);
if (language == null)
throw new ApplicationException("LANGKEYNOTEXIST");
CodeHighlighterEngine engine = new CodeHighlighterEngine();
engine.OutliningEnabled = false;
return engine.GenerateHtmlInline(string.Empty, code, language);
}
CodeHighlighterConfiguration GetCodeHighlighterConfig()
{
CodeHighlighterConfiguration config = (CodeHighlighterConfiguration)HttpContext.Current.Cache["CodeHighlighterConfig"];
if (config == null)
{
config = (CodeHighlighterConfiguration)ConfigurationManager.GetSection("codeHighlighter");
HttpContext.Current.Cache.Insert("CodeHighlighterConfig", config);
}
return config;
}
SyntaxLanguage GetSyntaxLanguage(string languageKey)
{
if (string.IsNullOrEmpty(languageKey))
return null;
CodeHighlighterConfiguration config = GetCodeHighlighterConfig();
foreach (string key in config.LanguageConfigs.Keys)
if (key.ToLower() == languageKey.ToLower())
return CodeHighlighter.GetLanguage(config, key);
return null;
}
}
In MediaWiki you can extend WikiText so that for example your xml tag is recognized by the parser. This way you can extend the HTML output. In this example you would write in WikiText the following statements:
<code language="C#">
public int x = 5;
</code>
In the extensions folder of MediaWiki you add a file called CodeHighlighting.php with the following content:
<?php
$wgExtensionFunctions[] = "wfCodeHighlightingExtension";
function wfCodeHighlightingExtension()
{
global $wgParser;
$wgParser->setHook('code', 'renderCode');
}
function renderCode( $input="", $argv=array() )
{
$result = SyntaxHighlighting($input, $argv['language']);
return '<pre>' . trim($result) . '</pre>';
}
function SyntaxHighlighting($code, $languageKey)
{
$location = 'http://localhost/SyntaxHighlightingWS/SyntaxHighlighting.asmx?wsdl';
$result = $code;
try
{
$client = new SoapClient($location);
$arr = array("code" => $code, "languageKey" => $languageKey);
$result = $client->Parse($arr)->ParseResult;
}
catch(SoapFault $exception)
{
if (strpos($exception->faultstring, "LANGKEYNOTEXIST") === false)
{
throw $exception;
}
}
return $result;
}
?>
Through the setHook method you can extend WikiText. Here the method renderCode is called when a XML element named 'code' is inside your WikiText. Calling a web service in PHP 5 is easy with the SoapClient object. If the language we pass does not exist, we simply return the original string.
One more thing must be done, is to add an include in the LocalSettings.php in your MediaWiki folder.
include("extensions/CodeHighlighting.php");
Finally:

Microsoft announces on the msdn site that service pack 1 for Visual Studio 2005 will appear around Q3 of 2006.
Internet Explorer 7 Beta 2 has been released to the public, and can be downloaded here. I installed IE7 on a clean WinXP SP2 without any problems through VPC. My blog site and IStaySharp.NET rendered correctly with IE7.  The coolest feature I found, is the integrated rss reader... 
I followed the Office 12 Ascend training in Paris that was teached by Patrick. The training was very successful and Patrick showed a lot of interesting stuff and demo's about Office and Sharepoint. So little time, and so much to play with, but thankfully there are the O12 labs which are very useful and detailed. On Patrick's blog you find a group photo with the team of Paris. Here are some pictures I took during the ascend training.
MediaWiki is a Wiki software licensed under GPL and written in PHP. Wiki allows users to easily add and edit content in a collaborative way. Wikipedia for example is one of the most popular Wiki's based on MediaWiki. Updated: 29 January 2006 Below you find the necessary steps for installing MediaWiki. - Download & install PHP 5.1.2 Installer. The installer creates a folder named c:\php
- Download PHP 5.1.2 zip package and extract all files in the folder c:\php
- Edit the php.ini file that resides in C:\Windows
- Change the extension directory: extension_dir = "c:/php/ext/
- uncomment mysql extension: extension = php_mysql.dll
- Download & install MySQL 4.1.16 (Windows (X86)).
- Create a virtual directory under IIS called phpmyadmin (e.g. c:/inetpub/wwwroot/phpmyadmin)
- Add the entry index.php in the documents tab.

- Download the latest phpMyAdmin and extract all files under the virtual directory of phpmyadmin.
- Edit the file config.default.php that resides in the phpmyadmin folder.
- Change the root password of MySQL.
- Browse to http://localhost/phpmyadmin
- Create a virtual directory under IIS called mediawiki (e.g. c:/inetpub/wwwroot/mediawiki)
- Add the entry index.php in the documents tab.
- Download the latest MediaWiki and extract all files under the virtual directory of mediawiki
- Browse to http://localhost/mediawiki & Configure.
- Add the line: '$wgEnableUploads = true' in the LocalSettings.php to enable uploads
 Troubleshooting: After installation you will notice that some pages give a warning, namely: Undefined index: REQUEST_URI in C:\Inetpub\wwwroot\mediawiki\includes\WebRequest This is a known issue and can be fixed.
Nowadays, is every kind of enterprise application more complex because there is the need to have much richer UI experience, integration with other systems, security, etc. Therefore it's important to have a good architecture and design of your application, so that you can better maintain and extend your application. In every enterprise application you have a dependency to data resources. These resources can be to a database, web service, registry, file system, etc. It's a good practice to encapsulate all these dependent resources into services, such that the consumer (caller of the service) doesn't need to know the implementation details and the origin of the data. That pattern is used a lot and is called a Service Gateway or Service Agent. There is a discussion on the difference between a Service Gateway that can be seen as consumer of a service and a Service Agent as a provider, but in the community both terms are used and mixed. The dependency between the consumer and the service is a contract which is typically a set of interfaces and business entities. In most cases, the service interface acts as a facade pattern, it encapsulates all subsystems underneath.  A typical example of a service agent is: public interface ICustomerAgent
{
Customer GetCustomer(int customerId);
Order[] GetOrders(int customerId);
}
Note that the interface doesn't expose any details about the underlying system (e.g. database, xml, etc.) and communication protocol (e.g. web service, remoting, etc.).
Porgramming the UI of an application is typically the most difficult part and a challenge to achieve encapsulation and loose coupling. Thankfully there is for .NET 2.0 the Composite UI and the Smart Client Baseline Architecture Toolkit which guides you to an architecture for developing smart clients. Offcourse there is still the bible that every developer should read/know, it's the GoF book that describes a set of design patterns.
One of the drawbacks of a designer like in Visual Studio.NET, is that it is so easy to drag and drop (in dutch I call it 'drag en drol') components, change some attributes and going through wizards for making your application. For prototyping and demo's this is good enough, but for real enterprise applications it's not. If you want you can write an application that has only one class (= form), named Form1.cs that includes all UI logic, business logic, data access, security, etc but that's not what we want.
Building the UI is basically populating UI controls with data that resides in business entities. This means that for example an array of customers that must be shown in a list, means that every customer entity must be translated to a ListViewItem (if we don't use databinding). In most of the cases this logic resides in the form/usercontrol itself, but in fact it can be seen as a separated responsability for mapping a customer entity to a ListViewItem and vice versa (like in SC-BAT). This means that we can have something like: public static class CustomerMapper
{
public static ListViewItem ToListViewItem(Customer customer) { ... }
public static Customer FromListViewItem(ListViewItem listViewItem) { ... }
}
And in your form/usercontrol you write: foreach (Customer customer in customers)
customerListView.Items.Add(CustomerMapper.ToListViewItem(customer));
In every project there are some OO concepts and patterns I always try to achieve maintainability and extensibility. Making good OO designs is in my opinion a matter of experience, creativity and making abstractions. My conclusion...
The art of OO programming is to define the set of responsabilities (= objects), to encapsulate and to interact them in a loosely coupled way.
The patterns & practices team introduces a new project, called Baseline Architecture Toolkit (BAT). It's a collection of carefully selected, designed, and integrated guidance assets which include: - Reference Implementations
- Application Blocks (such as CAB and EntLib)
- Hands-On-Labs
- How-Tos
- Guidance Automation Packages automating common tasks
- Documentation bringing all the parts together and describing the rationale behind the key smart client design recommendations.
The toolkit provides an effective way for architects, dev leads and developers to create high-quality baselines for their smart client applications, addressing non-trivial design and development challenges. The toolkit will provide reusable assets, guidance and examples for solving those challenges in the most common scenarios. Also, the guidance will be open and customizable, so you will be able to adjust it to your specific needs. There is a Smart Client Baseline Architecture Toolkit released on GotDotNet and it will be updated every 3-4 weeks and is based on the CAB. On Channel 9 you can find 2 casts about Smart Client BAT:
Here are some interesting blogs that are dedicated to Virtual PC There are some fundamental features in Virtual PC that you really have to look at. For example differencing disks, see HOWTO: Use Virtual PC's Differencing Disks to your Advantage and you can also compress your VHD files, see Compact Your VHD Files. Tip On several keyboard layouts and for example on a AZERTY belgian keyboard you need the [Alt Gr] key for the backslash, square brackets, etc. Inside Virtual PC the [Alt Gr] key doesn't work, therefore you can use an alternative for the [Alt Gr] key, which is [Ctrl] + [Alt]. Update: There is a hotfix now for the ALTGR problem.
The Windows SDK - Janary 2006 CTP is available for download and can be used for developing WinFX applications (WWF, WPF & WCF). This page give you the several components that are needed for developing WinFX applications, these are:
When I tried to install the SDK, I received the message that the user has cancelled the installation. In the config file I had the following statements:
0:03:18 vrijdag 20 januari 2006: [SDKSetup:Error] Config_Products_Configure: Configuration of Product Microsoft .NET Compact Framework 2.0 (failed): User cancelled installation. 0:03:18 vrijdag 20 januari 2006: [SDKSetup:Info] Config_Products_Configure: End configuration of product: Microsoft .NET Compact Framework 2.0 0:03:18 vrijdag 20 januari 2006: [SDKSetup:Info] Config_Products_Install: End installation of product: Microsoft .NET Compact Framework 2.0 0:03:18 vrijdag 20 januari 2006: [SDKSetup:Error] Config_Products_Install: Windows SDK Setup (failed): Installation of the "Microsoft .NET Compact Framework 2.0" product has reported the following error: User cancelled installation.
The solution was to simply remove the Microsoft .NET Compact Framework 2.0 from the Add/Remove Programs in the control panel. After that the installation was successfull.
For a long time I was thinking about purchasing a portable GPS device and I also wanted to replace my old GSM. One of the most popular devices is TomTom Go, but I felt it would be better to integrate both into a smartphone. TomTom also has a product called TomTom Mobile 5 that allows GPS navigation on your smartphone.
Therefore I bought the Qtek 8310 and TomTom Mobile 5 at PDAshop.be, I picked up the Navigation pack. The installation was easy, the only thing I had to do was to upgrade the TomTom software to TomTom Mobile 5.2 which can be found here, so that the software supports the Qtek 8310 which is the same as the i-mate sp5 (this must be chosen in the product upgrade). The TomTom package includes a mini-SD card which contains the TomTom software and maps that can be inserted into the smartphone.

I have to admit that everything works perfectly, the software is identically to the TomTom Go devices, there are no speed issues and the screen resolution is more than sufficient. Until now I didn't encounter any problems.
The smartphone itself has many many features, one of them is:
- OS: Microsoft Windows Mobile
- Quad-band GSM/GPRS / EDGE module
- GPRS functionality
- 1.3 Mega Pixels CMOS
- Mini-USB plug (Slave USB, Power In)
- Infrared IrDA SIR
- miniSD Card slot
- Bluetooth
- WiFi
- ActiveSync
- MSN Messenger, IE, etc.
- ...
And most importantly you can write .NET applications for your smartphone. If you download the Windows Mobile 5.0 SDK for Smartphone you get extra templates inside Visual Studio 2005 for writing smartphone applications.
Update:

Some years ago on a project I needed a usercontrol for code coloring SQL statements. At that time I reused a dll library that is used inside the query analyzer of SQL server. I wrote a little article about that topic, I think it gives some useful information about COM interop in .NET.
Today I released an add-in for Visual Studio .NET 2005 that allows you to drag components onto the designer surface. It's called ComponentDropper and you can even watch a movie to know what it does and how to use it.  A very good tool for screen capturing is Windows Media Encoder. It's from Microsoft and you can download it, if you have a legal version of Windows XP. Windows Media Encoder 9 Series is a powerful tool for content producers who want to capture audio and video content using the many innovations in Windows Media 9 Series including high-quality multichannel sound, high-definition video quality, support for mixed-mode voice and music content, and more.
On my current project we are developing a windows forms application in Visual Studio 2005. We are still using CruiseControl.NET for continuous integration and unit testing, because setting up a team foundation server would give an overhead right now. For unit testing we like to have the nice debug and built-in features of MSUnit and the unit tests automatically tested by CruiseControl.NET through NUnit. The good thing about the two libraries, is that they work through attributes and the common Assert methods are the same. The template we use for our unit tests, looks like: #if NUnit
using NUnit.Framework;
#else
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;
#endif
namespace MyUnitTests
{
[NUnit.Framework.TestFixture]
[Microsoft.VisualStudio.QualityTools.UnitTesting.Framework.TestClass]
public class MyTestClass
{
[NUnit.Framework.Test]
[Microsoft.VisualStudio.QualityTools.UnitTesting.Framework.TestMethod]
public void MyTestMethod()
{
}
}
}
We migrated our project to the new Composite UI. Yes, today a new release of the cab has been released. In the unit tests of CAB I noticed they did the same trick, but with aliases: #if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
#endif
namespace MyUnitTests
{
[TestClass]
public class MyTestClass
{
[TestMethod]
public void MyTestMethod()
{
}
}
}
Today I published the new IStaySharp.NET. It's rewritten in ASP.NET 2.0 and hosted by WebHost4Life. I also added a new FAQ entry about coverting FILETIME and DateTime, you will encounter FILETIME when you are using COM interop. There is a lot of coming during the next months. So stay tuned!
LAME is a very popular LGPL MP3 encoder. For a long time LAME version 3.90.X was recommended, now version 3.97b has been released. This version uses the -V setting, with a value from 0 (highest) till 9 (lowest) quality in VBR. More details about these settings can be found here. Instead of lossy compressions like MP3, there are also losless codecs like FLAC (Free Losless Audio Coded). No quality is lost, but the file size is much bigger. Here are some results in applying the above settings on a regular audio cd: | Setting | File size | Remark | | WAV | 721 MB | losless, uncompressed | | FLAC | 405 MB | losless, level 9 (highest) | | LAME -b 320 | 163 MB | lossy, CBR 320, highest possible quality | | LAME -V 0 | 105 MB | lossy, VBR | | LAME -V 0 --vbr-new | 102 MB | lossy, VBR but another algorithm (better quality and smaller) | You can assume that with the settings used here you cannot distinguish the mp3 from the original cd. A very good resource about audio, codecs and tests is Hydrogenaudio . This graph gives a nice relationship between the file size and audio quality for the LAME encoder. Between V0 and CBR320 setting, you see the file size increases by 50%, whereas the quality does not increase as much as that.
This year I purchased a server for persisting my data and for running applications that require intensive processing. For me it was very important to have a robust & performant way for archiving my data. Therefore I purchased a RAID card from Areca, the ARC-1120 . The raid card is connected through 8 HD's of 200GB from Western Digital in RAID 5. Areca is currently one of the best RAID cards available. This page contains an extended review with benchmarks .
My initial idea was to use my current ASUS A8N-SLI Deluxe motherboard, which has 2x PCI-E Express ports, and to use one port for the RAID controller. At that time it was still not possible, but now ASUS has provided a new BIOS driver which fixes the issue. After a lot of research and certainly the many chats I had with Bruno, I decided to go for a server motherboard. This is simply the most recommended way and is more robust, uses registered memory, has PCI-X ports, dual CPU, more memory slots, etc.
I wanted a server motherboard that contains dual CPU core support and featuring one or two PCI-E ports. This way I can easily upgrade in the future if it is necessary. Therefore I purchased the Tyan K8WE, which is an NForce Pro based server motherboard with 2x PCI Express x16 slots @full speed x16 lanes and has even a firewire connection.
A lot of hardware components means a large case. Therefore I decided to buy the U2-UFO case from Mountainmods. It's really a case with a lot of space and most important it can contain up to 9 HD's and it's compatible with an Extended ATX motherboard.
I am still configuring the server, but I will certainly post some benchmarks and experiences. In the mean time you can find the specs and some pictures of my server.

I updated the IStaySharp.WebBrowser control with some bug fixes. - DocumentText fix in IEBrowser
- Fix of member TranslateAccelerator in IDocHostUIHandler
- ScrollBarsEnabled fix in IEBrowserSiteBase
More information can be found on IStaySharp.
In .NET 2.0 you will notice that every data has among others an extra method called TryParse. TryParse and Parse are semantically the same but differ in the way they handle errors. Parse method will throw an exception if it cannot convert the string, whereas the TryParse method returns a boolean to denote whether the conversion has been successfull or not, and returns the converted value through an out parameter. int result = 0;
bool success = true;
string badValue = "12a45";
string goodValue = "1245";
try {
result = int.Parse(badValue);
}
catch {
success = false;
}
Debug.Assert(success == false);
Debug.Assert(result == 0);
success = true;
try {
result = int.Parse(goodValue);
}
catch {
success = false;
}
Debug.Assert(success == true);
Debug.Assert(result == 1245);
// int.TryParse
success = int.TryParse(badValue, out result);
Debug.Assert(success == false);
Debug.Assert(result == 0);
success = int.TryParse(goodValue, out result);
Debug.Assert(success == true);
Debug.Assert(result == 1245);
The reason why the TryMethod is introduced, is because exceptions are expensive. On http://www.codinghorror.com/blog/archives/000358.html you find a benchmark tool and you notice that the (default) Parse method is a lot slower.
One tip: For extensive use of string concatenation you use the StringBuilder class, for converting data types you apply the TryParse method.
The RealDN site, a blog site where employees of Real Software share their knowledge about technology, has been updated.
|