Posted by: joachimvandenbogaert | September 3, 2008

DateTime.ParseExact with yyyy-MM-ddTHH:mm:ss

The following page gives a nice overview of parsing .NET DateTime objects:

http://blog.stevex.net/index.php/parsing-dates-and-times-in-net/

Posted by: joachimvandenbogaert | June 27, 2008

Invoke an anonymous method

The link below shows how to invoke an anonymous method. It also discusses the InvokeRequired property and whether to test it when using Windows Forms.

http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/280f91aa27113fae?hl=en

Posted by: joachimvandenbogaert | June 20, 2008

Nice quote

“Isn’t happiness in life defined by how nicely your XML API lets you create XML documents?”

Fabrice Marguerie et al., (2008 ) “LINQ in Action”, p. 319, Greenwich: Manning Publications Co.

Posted by: joachimvandenbogaert | June 20, 2008

Simple Linq Query

I was looking for a query with dot-syntax that could simply sort an array of strings and was an alias of

from s in strings
orderby s descending

Found it here:
http://community.bartdesmet.net/blogs/bart/archive/2006/07/04/4115.aspx

var selection = strings.OrderBy(s => s);

 

Posted by: joachimvandenbogaert | June 6, 2008

Localization of software applications in .NET: some comments

.NET offers a good infrastructure for making your applications localization-ready. I found some difficulties however when implementing it. This is a small report of my experiences.

  1. If you really want to enable localization the easy way, don’t google for “Resourses” and “resx”, because this will give you a lot of tutorial/posts on using the ResourceManager. There is an easier way. I am not sure wheter it is the best way (more on that later) but in order to understand what .NET can do for you, we will use it anyway.Localization-ready strings are easily added by adding a new resources file to your project in your Visual Studio IDE. By using the Visual Studio application for adding strings to your resources file you can use your resources with IntelliSense enabled. It is important to give your strings an appropriate name and if necessary to store them in different resources files that denote different categories.

    (To be continued … )

Posted by: joachimvandenbogaert | May 28, 2008

Unit tests for static methods

Today I accidentally found out that it is very useful to test static methods with a repetition of at least two times. I forgot to initialize some values which caused some tests to break in the same run. The first time the method was called, everything worked fine. But the second time it was called, the test broke.

Luckily I found the source quickly and easily. But – without the tests – I can imagine that you continue working without ever detecting the mistake and finding out about it too late, not remembering anymore the static initializers.

Posted by: joachimvandenbogaert | May 8, 2008

Integrating HunSpell into a C# application

INTRODUCTION

I was asked to provide some spell cheking abilities to an application I am writing. After some googling I found two candidate spellcheckers. These were the features I was looking for:

  • Free to use/OpenSource
  • Active development community
  • Support for many languages
  • The ability to create custom dictionaries

NetSpell and HunSpell both fit the profile, but since HunSpell is OpenOffice’s default spell checker, I decided to go for HunSpell.

There was one problem though: there was no support for C#. The rest of this blog entry will be dedicated to the conversion of a native win32 application to managed .NET.

MANAGED vs. UNMANAGED

The main task consisted of making a C++ dll accessible via the .NET framework. It took me quite some time before I had all the information I needed. I even had to dig into some C++ in order to understand all the peculiarities involved.

The main problem with accessing unmanaged code is the definition of correct data structures to pass between the methods inside the managed code and the unmanaged code. The conversion between these datatypes is called “Marshaling”. The .NET framework takes care of this, but still you need to define all required data structures yourself. For example, a string in managed C# does not exist in unmanaged C++, so you will have to find a way to pass and return strings.

For frequently used dll’s inside the win32 api, a lot of work has been done by the community. http://www.pinvoke.net/ contains a large collection of, what I call “mapped” function signatures. Indeed, the larger part of the programming consists of merely mapping unmanaged C/C++ method signatures onto managed C#.

ENTER SWIG

The Pinvoke website is useful if you are working with win32 libraries, if you use other libraries , you have to find/derive the mappings yourself. But this is a very difficult and intensive job.

Luckily, there is http://www.swig.org/. Swig is a small commandline application that allows you to easily generate C++ and C# code for unmanaged code, it creates the mappings for you and works more or less in the same way a OR-mapper does. However, reading all the links above is still useful in the case the mapping is not perfect.

x86 vs x64 part 1

There was another problem to cope with: after I copied the project to my second development machine, which happens to run Vista 64-bit, my Unit Tests would not run. A System.BadImageFormatException was thrown for each method that involved the unmanaged C++ library.

The cause was of course the LibHunSpell dll that had been compiled for an x86 architecture. A solution would be to compile two versions of my library with each time a different dll (there is no such thing as conditional compile for different architectures in .NET), but since I wanted to have exactly the same unit tests for x86 and x64, regardless of which machine the code was running on, this was not possible.

To solve this problem, I implemented a Factory Pattern (http://en.wikipedia.org/wiki/Factory_method_pattern) to give the calling code the correct dll. If the code detects that it is running inside a 32bit environment, it loads the 32bit dll behind the scenes, otherwise it loads the 64bit dll. To determine which environment the application is running in, I used the IntPtr.Size property as discussed in the following newsgroup:

http://groups.google.be/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/96d020ac10f93c95/b864357a5f35f3aa?hl=nl&lnk=st&q=detect+64bit+C%23

The reason to go for the IntPtr method was that it would always give the correct environment, even if the application was loaded in 32bit mode on a 64bit OS.

Code edits

Some unit tests showed that the code generated by SWIG was not perfect. The C# bindings only seemed to work for the windows 1252 codepage. It was possible to spell check Dutch and English for example, but Russian in KOI8-R did not work. It took some time to figure out what was wrong. The following articles helped me a lot:

And of course also the java source code here : http://dion.swamp.dk/hunspell.html

They demonstrated the difference between a C++ string and a C# string. An ANSI C++ string is terminated with a zero mark (“\u0000”) inside the memory. So, actually HunSpell expects a string, in whatever encoding you configure, terminated by “\u0000”. I ended up changing some signatures, where an input string was replaced by a byte array (byte[]). In the code I then replaced the string by a zero-terminated string converted to a byte array with m_Encoding.GetBytes(). This seemed to do the trick.

Codepage mappings

Some more unit tests now revealed that a lot of HunSpell affix files use old encodings. Their names had to be mapped on Windows implementations of the code page. This required some research. The following links contain pages or papers that explicitely state that HunSpell codepages and Windows pages are equivalent:

x86 vs x64 part 2

After I got the most important method working (SpellCheck(byte[] word) properly, I ventured into getting the other methods to work. This turned out to be a frustrating chore for x64.

In x86 there is a suggest function that requires a ***char as an argument to store the suggestions for any given word in. Using the IntPtr, it was easy enough to convert this ***char to a C# string[]. The ***char is actually a pointer to an array of strings. So the address where the strings are stored is retrieved by Marshal.ReadIntPtr(pointerToAddressStringArray). By using the int that is returned by the suggest method, you know how many suggestions there are. So the addresses of the char arrays where the words are stored is retrieved by calling Marshal.ReadIntPtr on the address of the string array, with an offset that shifts 4 bytes each time. Then you simply need to call Marshal.ReadByte until you encounter a byte with a 0 value, to retrieve all characters.

I thought I could follow the same procedure for x64 but HunSpell seems to mess up the memory profoundly. Moreover there seems to be something totally wrong with how the characters are stored. If you have a look at the memory in a 64-bit environment you can hardly recognise any character.

For the moment, I stopped working on the 64-bit version. To fix it, I’m afraid I will have to dig into the C++ code.

Posted by: joachimvandenbogaert | April 28, 2008

Unit testing private methods

I was wondering whether it was possible to unit test private methods. I googled up some articels about it.

The main tendency was that it is not encouraged:

http://weblogs.asp.net/tgraham/archive/2003/12/31/46984.aspx

This blog presents a workaround by adding a public wrapper for the private method inside debugging code.

http://geekswithblogs.net/geekusconlivus/archive/2006/07/13/85088.aspx

This article shows you how to do things more neatly by using reflection in .NET:

http://www.personalmicrocosms.com/Pages/dotnettips.aspx?c=22&t=25

Although I agree that unit tests are a great help in driving your design, and make you program against an interface instead of against an implementation, I also find it useful to be able to test (as an exception) some smaller methods. Never say never.

On the other hand, I eventually found out that the private method I was writing, could be useful for other classes too. I ended up including the private method in a utility library. Seems like there is a reason for not unit testing private methods after all.

Posted by: joachimvandenbogaert | October 3, 2007

Regarding releasing resources

I read something very useful: apparently the “using” statement is an exception to the non-deterministic destruction behaviour in C#. Normally, when a variable goes out of scope, it will be collected at some point in the future by the Garbage Collector. The “using” statement makes sure that all objects that implement the IDisposable interface are being cleared up immediately after the “using” block exits.

This is an entry in Dutch, it only serves to remind me what the two patterns are for.

http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

De bovenstaande link naar het DAO design pattern geeft een excellente uitleg over hoe toegang te organiseren tot persistent data. Een DAO dient als scheidingslaag tussen data en business logic.

De Abstract Factory creëert een implementatiespecifieke Factory, naargelang het type dat gevraagd wordt (bijvoorbeeld een Factory voor SQL2005, één voor PostgreSQL, …). Deze Abstract Factory bevat abstracte methodes (bv. GetUserDao()) die als type een interface (bv interface UserDao) returnen.

De implementatiespecifieke Factories genereren implementatiespecifieke DAO’s die voldoen aan het interface contract van een DAO interface terwijl ze het contract van de Abstract Factory nakomen.

Op deze manier wordt ervoor gezorgd dat de client code via een interface eigenlijk een expliciete implementatie aanspreekt, zonder daarvoor te moeten weten hoe die expliciete implementatie in elkaar zit. Op deze manier kan gemakkelijk ook naar een andere DBMS implementatie overgeschakeld worden. Enkel de implementatiespecifieke code moet gewijzigd worden, bv

DaoFactory daoPostgreSql = DAOFactory.getDaoFactory(DaoFactory.DbmsType.PostgreSql);
DaoUser = daoPostgreSql.GetDaoUser();

Uiteraard moet PostgreSqlDaoFactory : DaoFactory geschreven worden alsook
PostgreSqlDaoUser : DaoUser

« Newer Posts - Older Posts »

Categories