Author: Guy Smith-Ferrier
Publisher: Addison Wesley
With the reach of the Internet today, “local” is taking on a new meaning. Today’s business is increasingly being conducted in a global, multi-lingual and multi-cultural environment. As software developers, the concept of internationalisation (a word which, ironically, is itself spelt differently within the English speaking community) and indeed localisation is something we need to be more than aware of. However, it’s a topic that attracts a lot of attention, yet few have written about in such depth as Guy Smith-Ferrier. Indeed, in my experience, a lot of authors who attempt to cover internationalisation have, despite best efforts, sent their intended readers into a comatose state – internationalisation as a topic is perhaps not the most exciting topic to choose to read about! However, I’m pleased to report that Guy manages to inject enough humour and witty anecdotes such that as a reader, I was kept interested.
Foreword & Preface
Microsoft’s International Project Engineer Jesper Holmberg provides a short and sweet introductory paragraph. Jesper laments about the difficulties developers faced when attempting to “Internationalise” applications in the Win32 era. He goes on to confirm that the .NET Framework is not the panacea to our internationalisation woes and that as developers, we still have to possess a good understanding of the issues behind culture-independence and localisation. Mention of two definitive texts, Code Complete (Steve McConnell) and Writing Secure Code (Michael Howard) suggests Jesper believes that .NET Internationalisation deserves similar pride of place on your bookshelf.
The book’s author then provides a 3-4 page Preface that explains the real need for internationalisation, citing facts such as France, Quebec and Canada have laws prohibiting the hosting of English-only web-sites. Guy makes good use of these interesting facts throughout the book, they serve to keep the reader interested, and they certainly worked for me. He then goes on to extol the virtues of Visual Studio 2003, choosing to remind us of its lack of internationalisation support for ASP.NET applications, something that was rectified in Visual Studio 2005.
A Roadmap for the Internationalization Process
This chapter sets the scene, explaining that internationalisation isn’t just about translating all the text (which is the simplistic view). Guy compares technical work, including internationalisation, to the false summits that a mountain climber encounters – as one technical plateau is reached, another is discovered.
It doesn’t take the author long to mention internationalisation buzzwords: Unicode, mirroring, cultures, right-to-left. Indeed, no time is wasted explaining that, if you’re serious about internationalisation, using a Unicode version of Windows is highly recommended.
A discussion about .NET 1.1 and 2.0 explains that some of the “good stuff” in .NET 2.0 can be retrofitted into .NET 1.1. As one might expect, newer in this case is better as the author extols the virtues of Visual Studio 2005 and .NET 2.0. He cites greater functionality for typed resources in the IDE, property reflecting in WinForms and repeats the fact that ASP.NET built using Visual Studio 2005 now supports localisation.
Generally speaking, Latin languages, such as French, German and Spanish, are considerably easier to work with than East Asian languages such as Chinese, Japanese and Korean (CJK). He provides an explanation of how the operating system might deal with rendering right-to-left languages, using mirroring and font-linking to find characters (glyphs) as used in the CJK languages. .NET 2.0 support for custom cultures is touched on, yet another indication that you should be using .NET 2.0 over .NET 1.1. Given the complexity of custom cultures, the author recommends that you use virtualisation (VirtualPC) in order to test your applications.
Resource formats (strings, bitmaps, icons, and anything else in your application that needs to be localised) are discussed albeit briefly. The virtues of using Visual Studio 2003 or 2005 for resource editing are pushed home once again.
Languages and cultural formatting discusses the subtleties of intra-language variation, e.g. the differences between US English and British/UK English. Similar differences exist in other languages, e.g. French in Canada differs from French in France.
Windows Forms Applications outlines some of the problems you might come up against if you have used .NET Framework dialog controls, such as MessageBox. These controls use resources from the operating system and the .NET Framework Language packs – you could end up with an application that is part French and part Spanish for example!
ASP.NET Applications provides a further reminder that we really should be using .NET 2.0 and Visual Studio 2005. The author firms home the fact that internationalising an ASP.NET 1.1 application is possible, but that it involves a lot of manual effort and enjoys little tool support. There’s an interesting discussion about the relative merits of absolute versus relative positioning of controls, especially if you plan to use right-to-left languages such as Arabic, Hebrew and Persian [Farsi].
Another “isation” is introduced: Globalisation. The author presents a non-exhaustive collection of cultural misconceptions. For example, the Windows Program Files folder isn’t always known as “Program Files” on non-English versions of Windows. This was an interesting topic and one that got me thinking – cultural misconceptions are so often ignored: how often have you made do with “mm/dd/yy” date formats? Luckily, the .NET Framework classes (not dialog controls) understand such things and do a pretty good job sorting them out.
Localisation brings with it further decisions that you must consider. For example, once your application has been localised into, say, French, what language do you want your exceptions thrown in? It’s likely that they’ll be read using a different language. The author describes the problems of automating the translation process, citing examples such as hotkey assignment as being a significant problem – the most logical key may not be the key that gets assigned.
Machine translation is touched on; the need for a human to review the automated translation should go without being said, however the author, rightly so, chooses to make sure by reminding us of this need. Human verification is a form of testing and is a topic that the author firmly believes in. Indeed, he provides a brief discussion here and a full chapter on the topic of static code analysis using FxCop – a tool that uses rules to enforce design decisions and application choices/decisions.
This 13-page chapter was a good introduction to the concepts behind internationalisation. It sets the scene for the rest of the book rather well, using the occasional forward reference to chapters, thus indicating that there’s more detail available later on in the book.
Unicode, Windows, and the .NET Framework
As the title suggests, this chapter provides a great overview of where Unicode fits into the Windows operating system and the .NET Framework. It provides some super tips about using virtualisation via VirtualPC in order to test your internationalisation efforts. A succinct and to-the-point explanation of the Windows Multilingual User Interface (MUI) pack follows – appropriate use of screenshots makes it fairly lively. This chapter closes with a description of dotnetfx.exe, a file that is used by millions of people worldwide – it is the setup dialogs from the Microsoft web-site that the determine which language dotnetfx.exe uses once it has been downloaded.
An Introduction to Internationalization
So here we are three chapters in and we’re only just getting an “Introduction” – this isn’t a criticism, it reflects the amount of groundwork that has to be done in order to provide a solid understanding of internationalisation and all it entails. This chapter discusses the notion of World-Readiness. Specifically, it covers internationalisation, globalisation and localisation (often abbreviated to I18N, G11N and L10N). Interestingly, and this serves to repeat that internationalisation is not just about changing all the text in an application, this chapter also covers the concepts of localizability and customisability. Customisability – your application provides a means of handling different VAT schemes; localizability – your application essentially uses replaceable Resources that can be changed at run-time.
The author then provides an explanation of those culture strings that we’re so used to seeing as part of downloads, e.g. en-US or en-GB
Resource files are covered in some detail, with particular reference to Visual Studio 2005 – although box-outs provide advice for those still working with Visual Studio 2003. I was pleased to see the author provide an example of localisation using nothing more than MessageBox.Show(). The example is built from the ground up and becomes more complex as the chapter progresses – it goes from a basic .NET 1.1 example right through to using a strongly-typed resource file in .NET 2.0. The author clearly believes in strongly-typed resource files – he has written his own strongly typed resource builder class for .NET 1.1 and makes it freely available to readers.
Windows Forms Specifics
This chapter, as its name suggests is focused wholly on .NET Windows Forms. The example here, as the author confirms, is simplistic, which is a good thing. The example goes through the steps required to localise a form using the property assignment model. On the premise that the property assignment model may seem like it will have a performance impact, I was pleased to see the author include links to Brian Pepin’s Localisation Filter.
Once again, the support for internationalisation in Visual Studio 2005 shines through. However, good use of box-outs help those developers still using Visual Studio 2003. In fact, this chapter is littered with useful tips and gotchas that will make your internationisation task that bit easier.
This chapter also demonstrates that the Win32 API is alive and well. The need to invoke Win32 methods is evident when the author describes trapping the WM_SETTINGSCHANGE event. It’s worth noting that even in .NET 3.0, some Win32 API calls still have to be made; wrappers don’t exist as yet.
A good explanation of where localisation support originates is proved by means of a simple example. We are presented with the Print Preview Dialog box in both English and German. The operating system provides all of the localisation support, except for the Print Preview Dialog – which is provided by the .NET Framework and the .NET language packs.
In addition to an introduction to the WinRes tools, its pros and cons are covered. Further, the author makes some useful recommendations as far the use of the WinRes tool goes.
Surprisingly, if you’re new to internationalisation, this chapter includes a reasonably large description of ClickOnce, including a little bit about MSBuild. I suppose when you think about application deployment, tool support for internationalisation is very important – hence it’s good see it covered here.
By their very nature, ASP.NET applications are pushed out to the global audience, therefore the need for them to support internationalisation carries even more impetus. However, as the author has already mentioned a few times (unlike you and I, Dear Reader, the general public need to be told something three times before it sinks in), ASP.NET 1.1 internationalisation was “all your own work”. With ASP.NET 2.0, all that changed.
This chapter covers both 1.1 and 2.0, taking a reasonably deep dive into some code that has been automatically generated (which serves as a good learning tool). Code that helps internationalise 1.1 applications is also presented – it certainly is a manual process, you should endeavour to upgrade to 2.0 (or greater) as soon as is possible! Refreshingly, the author provides solutions and an analysis of how well the solution goes about dealing with this problem – such an approach only serves to enhance the reader’s understanding of the issues behind internationalisation.
Localisation in ASP.NET 2.0 is clearly a superior beast, a point well made by this author and one this reviewer has chosen to repeat throughout this review.
Astute readers will have noted that I have chosen not to localise this chapter’s title. Indeed, this is my only real complaint about this book – it’s somewhat ironic, here we have a book about internationalisation, encompassing localisation, yet throughout this book, we still see the zee, the zed! A small point.
The .NET framework provides a Globalization namespace (System.Globalization to be precise). The author cuts to the chase and suggests that we can add a lot of internationalisation support simply by using this namespace.
Further use of appropriate examples, such as the removal of the Turkish Lira at the end of 2005, provide us with insights into the nuances of internationalisation and serve to confirm the author’s experience in this domain. Indeed, I was particularly pleased to discover a few pages that discuss Sort Orders, including a very interesting table highlighting a variety of different sort orders (behaviours) found in many languages.
A detailed explanation of date, time and currency formats is provided. The author goes to reasonable lengths to cover this topic such that we do not lose interest in what is a very precise subject. I was very pleased to see coverage of the security issues behind the internationalisation of domain names.
Middle East and East Asian Cultures
The first 6 chapters of this book deal with internationalisation using traditional Latin languages that use a left-to-right notation. Whilst left-to-right languages make up a large part of the world’s written text, an equally large part is covered a wide variety of non-left-to-right languages such as Arabic, Hebrew and Persian (Farsi) to name but three.
The author opens this chapter with an explanation of how to install Supplemental Language Support, such that we can render right-to-left languages. Mention of Windows Vista, which already has support for supplemental languages built right into the operating system, merely serves to confirm that the author has endeavoured to get this first edition as up to date is as possible.
This chapter makes more use of screenshots than other chapters. This is a good thing as a couple of new concepts are introduced, most notably unmirrored and mirrored Windows Forms. Whilst I have seen Arabic Windows XP before, it was useful to see it presented in this chapter – it is, after all, probably the first right-to-left language that most of us are familiar with. Common questions, such as “which version of Windows support mirroring?” are succinctly answered.
There would appear to be a few subtle mirroring differences between .NET 1.1 and 2.0. A few screenshots present these differences better than words could describe.
As with most development related topics, it’s very easy for us to completely miss the blindingly obvious: things other developers assume is common knowledge is often easily missed whilst traversing the learning curve. This chapter aims to provide us with a collection of key decision areas.
The chapter opens with an explanation of the Windows font technology. Whilst we take fonts for granted, care must be taken when selecting fonts if you are internationalising your application. That said, the basic font information provided by Windows isn’t really much help. I was therefore somewhat grateful when the author introduced me to Microsoft’s Font Property Extension tool – it plugs a gap by providing information relating to each font’s Supported Code Pages and Support Unicode Ranges.
A further discussion covers the concepts of font linking and font fallback: terminology that could easily pass you by. Font linking first appeared with Windows 2000 – it essentially provides a means of negating the need to switch fonts in order to display different glyphs or characters. The author augments this chapter with a few screenshots that depict font linking graphically. Font fallback, on the other hand, allows fonts to rely another font that can be used to display letters from other fonts as and when required. Interestingly, font fallback is essentially hard-coded. That said the author explains how to hack the registry to change the fallback fonts.
We’re all guilty of hard-coding something at some stage in our careers: font names are certainly key candidates for such bad, but commonplace, behaviour. If you were planning to hard code font names for any reason, please think again as Windows can substitute font names, thus making any font name comparisons that you might make rather useless. Another example that we’re all guilty off is string concatenation: such behaviour does not bode well for internationalised applications. Luckily the author offers a solution using String.Format.
The localisation of Exception is covered from a .NET 1.1 and 2.0 perspective. The author introduces us to his own ExceptionFactory, a small class that you are free to use in your own applications in order to manage your localised exceptions.
Most well-written applications make good use of Hot Keys – these are the identified (in Windows Forms) using underlined letters. As you might imagine, Hot Keys create many problems for both manual and automatic translators. The author is once again kind enough to provide us with some of his own code. The HotKeyAssignment class solves many of the problems, not least the human effort required to work out the Hot Keys in the first place – how often have you duplicated a Hot Key? The use of Hot Keys in an ASP.NET application is also considered in this chapter.
Layout of controls in a Windows Form is a trivial process. However, it’s not so trivial if you’re looking to localise the form. For example, given a text box and a label, does the label go above the text box or to the left of the text box? Personally, I’ve always put it above the text box. This is an important design decision as English language descriptions tend to be shorter than their foreign counterparts (such as German, or Welsh). An explanation of the .NET features AutoSize, AutoEllipsis, TableLayoutPanel, FlowLayoutPanel then follows, decorated by many useful screenshots.
Machine Translation (MT) appears to be fraught with danger. There is no single translation for most of the words we might want to localise in an application, therefore great care must be taken. The author goes to great lengths to make this point. Indeed, in order to demonstrate some of the issues surrounding MT, the author announces that this chapter will see the development of a cut down MT (a pseudo localiser) and a Translator Evaluator that is able to test the performance and compare the success of automatic translators. After a fairly detailed explanation of the author’s own a pseudo localiser, he then focuses on Internet-based translations tools, such as AltaVista and the Office 2003 Research Service (which includes a detailed examination of the WorldLingo translation service and the HTTP web requests and responses required to use the service).
The Translator Evaluator made for an interesting examination. It is pre-loaded with at least seven translation tools and it is capable of translating text from one language to another and back again. The reason why we translate the translated text back to its original language acts as a means of verification – it provides some level of confidence (an indicator if you will) in the translator’s ability.
Managing the resources in your application, even in a relatively small application, is no mean feat. Every button, every label, every groupBox, etc. has a Text property that needs to have a value associated with it. This chapter discusses two utilities written by the author: a Resource Administrator and a Visual Studio Add Resource String Add-In. Visual Studio 2005’s Resource Editor is considerably better than its Visual Studio 2003 counter-part – the Resource Administration tool provided by the author allows a Visual Studio 2003 user to enjoy Visual Studio 2005 functionality.
The author proceeds to walk-though a typical usage scenario, using a mixture of explanatory text and screenshots. I was pleased to see that an Integrity Check routine is built into the Resource Administration utility – it looks through all the resources seeking out missing entries. A good sanity check.
Adding resource strings, as the author states, is something that is often postponed. If you are a developer and you are “in the zone”, the last thing on your mind is adding a resource string. The Resource String Add-In helps make that process quicker and encourages the creation of resource strings as and when they are required, i.e. during development rather than as an afterthought. Since the book currently targets both Visual Studio 2003 and Visual Studio 2005, the author very kindly explains how we go about installing the Add-In in both versions.
The source code for both utilities, the Resource Administration utility and the Add Resource String Add-In is supplied as part of the download material for this book.
The remainder of this chapter goes on to explain how the utilities go about reading and writing resources. Extensibility is one of the author’s goals for these utilities. If you are interested in the low-level detail of how these utilities work, this chapter is worth reading.
We know that .NET 1.1 and 2.0 support globalisation via the use of cultures, the latter being better than the former. .NET 2.0 applications support the notion of custom cultures, whereby an application developer may define a new culture. This chapter explains how we might create, register/unregister and deploy custom cultures. In the global marketplace, we need custom cultures to deal with such things as the Spanish speaking population in the USA (es-US).
This chapter presents an end-to-end example of how we might go about building our own custom culture. Small steps are used to take us through creating a new culture, installing it and uninstalling it – the example is small enough such that the code used in this chapter is now overwhelming.
One gotcha is presented in this chapter. It is a gotcha that we are all very familiar with: DLL hell. Custom cultures are all public – when you install a culture, you have no idea whether somebody else has created a culture with the same name. The author refers to this as Custom Culture Hell. Luckily, he goes on to explain a few workarounds that can alleviate this problem. One to be aware of.
Custom Resource Managers
Out of the box, .NET 1.1 and 2.0 provide their own resource managers – System.Resources.ResourceManager and System.ComponentModel.ComponentResourceManager. This chapter explains all that is required to build your own. Why would you want to do this? Well, if you do not wish to use .resx files, writing your own resource manager to read a custom file format (or use a database) is one way to avoid such files. This is a fairly heavy going chapter littered with code snippets, command-line statements and screenshots. Luckily, the author provides us with examples of custom resource managers, including one that demonstrates how a custom resource manager might make use of a SQL Server database. At 80+ pages long, this is one of the more advanced chapters.
Testing Internationalization Using FxCop
Automating anything that a developer does is a good thing. FxCop automates the “checking of code”, ensuring that the developer doesn’t forget to adhere to a best practice, internal design standard or even the rules of localisation of your application. FxCop is a static code analysis tool that is available for both Visual Studio 2003 and 2005 – essentially, you run it against your code and it tells you which rules you may have broken or come close to breaking.
This chapter provides a good overview of how best to use FxCop in both a WinForms and ASP.NET environment. The author provides a good discussion around FxCop’s built-in globalisation rules – some of the rules have “interesting” short descriptions, hence the discussion is rather useful. Clearly the author has spent a lot of time looking at the way in which .NET handles globalisation and localisation, as the inclusion of decompiled IL demonstrates.
In conjunction with FxCop, this chapter provides a very detailed deep dive into the things you should be looking to include in your application to internationalise it. Whilst it’s only 50+ pages, it does present a reasonable amount of code, but packs a lot of explanation.
The remainder of the book covers the author’s own translator application (available for download from the web-site mentioned in the Useful Resources section), two Appendices and an Index. The Information Resources appendix is very comprehensive, covering everything from books, good web-sites, blogs, free tools and commercial tools.
The only thing missing from this book is coverage of .NET 3.0 and 3.5, but that’s more to do with the timing of this review vs. publication date. I would expect to see that in a subsequent edition. The liberal use of screenshots and care to ensure that code snippets do not stretch to more than a page is noted and is very much welcomed; there is nothing worse than code samples that run to many pages. Good use of break-out boxes to cover key points is also a nice touch.
This is a good book that is well-written. The author, Guy Smith-Ferrier has done a good job making a subject that most of us shy away from more approachable. If you need to internationalise your .NET application, this book is for you. However, and this is not a criticism, because of the subject matter, this book is not an easy read: it is a book that you will need to treat as a core reference. So to that extent, if you need this book, it will be on your bookshelf along with other core reference and cult books.
Overall Book Rating
Rating: 4.5 / 5
This book’s web-site: http://www.dotneti18n.com/ (includes two sample chapters, all the code for Visual Studio 2003 and 2005 and and updates page where you can find on-going improvements)
The author’s web-site/blog: http://www.guysmithferrier.com/
About the Reviewer
Craig writes approximately fifteen articles per year, over 50 of which have been published. In addition, he has prepared and delivered over 40 presentations at developer conferences and user group meetings throughout the UK and Germany. All of the source code and PowerPoint slides are available from his web-site: http://www.craigmurphy.com
He is a regular contributor to The Delphi Magazine, the DotNet Developers Group magazine and has written for ASPToday, International Developer and Computer Headline.
Craig is one of the founding members of Scottish Developers; he works closely with Agile Scotland. After playing a major part in the organisation of the UK’s first DeveloperDeveloperDeveloper event, he continues to be part of the organising team and has helped organise five further DDD events so far!
In particular, he will speak about SOAP, web services, XML, XML Schema, XML Topic Maps, XSLT, Delphi, and C#. He will also speak and write about Test-Driven Development (TDD) and eXtreme Programming (XP). Craig is a Certified ScrumMaster (CSM), Microsoft Most Valuable Professional (MVP Connected Systems) and holds an Honours degree.
© Craig Murphy 2007
Technorati Tags: .net, guy smith-ferrier, internationalisation, internationalization, localisation, localization, book review, scottish developers, agile scotland, the delphi magazine, dotnet developers group, asptoday, international developer, machine translation, custom cultures, fxcop, globalization, globalisation, custom resource managers, resource administration
Thanks for a great in-depth review of this book. You’ve just saved me a great deal of time sifting through the chaff to get to the good stuff 😉
[…] I reviewed Guy’s book, .NET Internationalization, over here. […]
Great job. Your creation will be useful for many generation to come. Cheers!