2012-10-29

Forcing a Culture in the business logic

Not exactly a new topic, but a reminder. In my opinion, it's a good practise for your application business logic not to assume that it will be run in a particular Windows configuration, namely a specific culture. An "innocent" ToString() or Parse() method call in a double or DateTime struct is all that takes to break your code. Last week that happened at the office, some of our unit tests were only failing on some development machines. It turned out that some of team members have Windows configured to use GB English regional settings, while others have been using PT Portuguese settings. One approach to fix this is to force a culture in all calls of these methods (US English, for instance), but I think that is boring and easy to overlook. I prefer to force the culture for all calls, something like:

Thread.CurrentThread.CurrentCulture = 
   new CultureInfo("en-US");

 Here's how I have been doing it, depending on the component type.

WCF Service

Usually, I would put the code line in the Application_Start() method of the Global.asax class, since it would apply to every service in the project. However, the last time I've did it, we were using Castle Windsor for dependency injection, and this doesn't seem to work, as the container instantiates the service object in another thread. Solution: put the line in the service constructor.

Since we are also using ThreadPool for some of the tasks, I also had to add the line to the callback method.

Yes, I could also have used the <globalization> tag in the web.config, but that would imply activating ASP.NET compatibility in WCF, which I didn't want to (no problem on doing so, but I just wanted to avoid unnecessary entropy).

Console Application / Windows Service

Usually, I would just put the line in the Program class Main method, but since we are using TopShelf to abstract some of the Windows service boilerplate code, I had to put it elsewhere. Basically, in the WhenStarted() callback.

NUnit Test

Unit tests are basically class libraries, so there is no central point method. The best I came up with was putting the code in the StartUp method, for every unit test class. Since I'm being lazy, in reality I've only added it in every test class that was failing because of culture settings.

No comments:

Post a Comment