Category: General

Keyboard shortcut of the week

My team at work is far from agile, but I’m trying to smuggle some ideas and practices, according to the old Latin proverb gutta cavat lapidem, non vi, sed saepe cadendo.

Recently, as a small way of continuous improvement I suggested each week we print some Visual Studio or ReSharper keyboards shortcut, that we didn’t know or use, and which can help us do some things a little bit faster.

Here’s the first one:

DSC00117

It’s pinned to a cork whiteboard in a location that everyone looks at it few times a day. Hopefully by the end of the week everyone will have it memorized, as we move to another one.

And you? What small things you do to improve your skills (or your team’s)?

Technorati Tags:

Multilingual .NET applications. Enter .NET localization

Creating multilingual applications is a huge topic. There are whole books devoted to it, and if you’re serious about it, you should definitely read those, because what you see on surface, is only the tip of an iceberg.

If you only want to play with localization or need a quick reference, hopefully this post will help.

Fist thing is, .NET is really well thought of if it comes to localization, so if you know what you’re doing, it’s pretty painless to create application that will be easy to translate to other languages (localization is a LOT bigger topic than showing labels in different languages, but I’ll leave this topic out.)

Second thing is, localization mechanism in .NET is greatly based on conventions, and it’s what we’ll focus here.

First obvious rule is, that each string, picture, video… generally speaking localizable resource must not be hardcoded.

If you don’t hardcode resources where do you keep them? In (surprise) Resources file. Generally you can use .resx files, or plain .txt, though the latter are useful only if you only keep strings.

resourceFile

Visual Studio has pretty good support for editing resources in .resx files, and later I’ll show you another tool that can do it as well.

To access the resources programmatically you need ResourceManager class. To instantiate it you need to give it the part to resources within an assembly, and the assembly itself. If it’s a little bit unclear, here’s the example:

resourcePath

If the Visual Studio project is named LocalizableApp, and the .resx file we want to use is in folder Properties, and the file itself is named Resources.resx, the whole base name for the resources is “LocalizableApp.Properties.Resources”.

That’s where the compiled .resx file (.resources) will be located within the assembly. You can see it, if you open the compiled assembly with Reflector.

resourceLocation

So to instantiate the ResourceManager you’d write code similar to the following:

var manager = new ResourceManager("LocalizableApp.Properties.Resources", typeof(Program).Assembly);

Each resource is identified by it’s unique name string. For example in the picture below, we have two resources with names, “greeting” and “howAreYou”

resourceEditor

You use these names to get the values of the resources. The resource manager does its magic, to provide you with resources best matching the CultureInfo you provided. If you don’t provide any Culture, current thread’s CurrentUICulture is used. So if you write:

Console.WriteLine("{0} {1}", manager.GetString("greeting"), manager.GetString("howAreYou"));

The CultureInfo object held in CurrentUICulture property of currently executing thread will be used. The default value for this property is the same as language version of Windows OS the program is executing on, which is reasonable. If your user uses Polish Windows she will probably want to interact with Polish version of your app as well.

You may not rely on this default though, and either override the Thread’s property, or specify the culture explicitly when calling methods on ResourceManager, like so:

culture = CultureInfo.GetCultureInfo("pl-PL");
Console.WriteLine("{0} {1}", manager.GetString("greeting", culture), 
    manager.GetString("howAreYou", culture));

Of course you wouldn’t hardcode the culture the way I did in the example, because it would defeat the purpose of using culture in the first place.

OK, so how to add another language?

You have the .resx file with the default, fallback resources, right? So now all you need is either send the file to a localization company, sit back and enjoy life, waiting for them to do the hard job, or do it yourself. To go with the latter option, you may want to use a tool to edit resource files, called Resourcer, by Lutz Roeder (Reflector, people!).

resourceResourcer

You can easily edit any kind of resources in it (not only strings). When you’re done translating your resources, save the file as .resources file, using following pattern: {baseResourceName}.{culture}.resources. For example if you were to translate our example app, to German language as spoken in Germany, you’d save your edited file with the following name: LocalizableApp.Properties.Resources.de-de.resources

It is important to obey this pattern, as by convention, this is what ResourceManager expects. If you fail to obey it, ResourceManager will not be able to pick your translated resources and will fall back to the default.

Having translated and properly named .resource file we need to make a satellite assembly out of it. To do it, you need Assembly Linker (al.exe) tool that is part of .NET SDK.

al

There are multiple properties you can set with al, the minimal version to get valid satellite assembly is shown on above screenshot. One thing that’s important to note, is the name of resulting satellite assembly. Again, by convention it has to be {NameOfBaseAssemblyWithoutExtension}.resources.dll, so if our application assembly was named LocalizableApp.exe, satellite assembly must be called LocalizableApp.resources.dll

Notice that the name of the assembly is the same for every culture. So how do we deal with that. Obviously we can’t have two files with the same name in one folder. The way it is handled, is through subfolders. Each satellite assembly is held in a folder which is named after the culture of the satellite assembly.

resourceFolders

For example if our LocalizableApp.exe is held in a folder, let’s say Debug like on the above screenshot, the de-de satellite assembly would be Debug\de-de\LocalizableApp.resources.dll and for instance pl assembly would be in Debug\pl\LocalizableApp.resources.dll.

I hope this is all clear by now. The greatest thing is, to add new language you don’t even need the actual base assembly. All you need is its resources and their location within the assembly.

Technorati Tags: , ,

Five books I wish existed

I read a lot of blogs. I love them. However, I believe they are not the best medium if you want to learn something from A to Z. That said, here’s my wishlist of books that I wish existed.

  • “Creating maintainable software architecture” – Oren Eini
  • “Maintainable software development” – Oren Eini
  • “Advanced Windows Communication Foundation from the inside” – Nicholas Allen
  • “Building service oriented software” – Udi Dahan
  • “Presentation patterns with WPF” – Glenn Block (There is more broad book “Presentation Patterns” to be written by Jeremy D. Miller)

Those are people, who have deep knowledge on their respective topics, and could create really great books. What’s your list of books you wish existed? Post your picks in the comments.

Technorati Tags:

You don’t get the C# 4.0, do you?

Sorry for the daring topic, but that’s really what comes to my mind when I read or hear people whining about C# loosing purity/object-orientation/strongly-typedness/goal/insert your favorite here, with the advent of version 4.0.

To sum it up, there are four major new areas of improvement coming up with the forthcoming version of the language, as outlined by Charlie Calvert in “New Features in C# 4.0”.

  • dynamic keyword (type) along with all its implications.
  • Optional and named parameters.
  • Co/Contra-variance of generics
  • Few additional features geared towards easing the pain of dealing with COM

I don’t really care about COM, and covariance and contravariance is not really controversial (at most people will grumble that they have to learn how to use it properly), so I’m going to leave those two out, and concentrate on the first two features.

Optional and named parameters wouldn’t probably even make it into the language if it wasn’t for improving interoperability with COM where they are heavily used. And I’m glad they did. Really. Major argument people raise when it comes to them, is that they add no value to the language. Anything you can do with them, you can do with method overloads. Yes you do, but step forward if you can tell me straight into my face, that you’d rather write this:

public virtual void AddComponent(String key, Type classType)
{
    AddComponent(key, classType, classType);
}
 
public void AddComponent(string key, Type classType, LifestyleType lifestyle)
{
    AddComponent(key, classType, classType, lifestyle);
}
 
public void AddComponent(string key, Type classType, LifestyleType lifestyle, bool overwriteLifestyle)
{
    AddComponent(key, classType, classType, lifestyle, overwriteLifestyle);
}
 
public virtual void AddComponent(String key, Type serviceType, Type classType)
{
    AddComponent(key, serviceType, classType, LifestyleType.Singleton);
}
 
public void AddComponent(string key, Type serviceType, Type classType, LifestyleType lifestyle)
{
    AddComponent(key, serviceType, classType, lifestyle, false);
}
 
public void AddComponent(string key, Type serviceType, Type classType, LifestyleType lifestyle,
                         bool overwriteLifestyle)
{
    /*actual code*/
}

than this:

public void AddComponent(string key, Type serviceType,
    Type classType: serviceType,
    LifestyleType lifestyle: LifestyleType.Singleton,
    bool overwriteLifestyle: false)
{
    /*actual code*/
}

It means less code to write, less code  to maintain, less code that you’d do probably copy/paste, which attracts bugs like a dead dog attracts flies. And while we’re talking about bugs, think about methods like this:

public XPathNodeInfoAtom(string localName, string namespaceUri, string prefix, string baseUri,
                         XPathNode[] pageParent, XPathNode[] pageSibling, XPathNode[] pageSimilar,
                         XPathDocument doc, int lineNumBase, int linePosBase)
 
 

What is really the chance that you’ll get all the parameters right each time you call them, not mixing the order, and passing localName instead of prefix, or the other way around? Think about how utterly hard to read the code is, especially if you don’t have well named variables you pass as parameters. This can be fixed by explicitly passing each parameter along with its name. And it’s not the case only for methods that take that many parameters. One common mistake I see is in constructors of ArgumentException and ArgumentOutOfRange exception, both of which take parameterName and message as a value, but in different order.

The feature that gets the most bad publicity is the dynamic programming capabilities introduces thanks to dynamic keyword. That’s what makes people lament, that they will no longer be able to rely on IntelliSense and the compiler, and that this is the advent of apocalypse.

Well, rest assured – world will stand tomorrow, just like it stood yesterday. The whole dynamic thing gives you three things:

  • Simplified programming model for things you had to rely on strings (ergo, no compiler checking anyway) in the past, so no harm done here.
  • Improved performance as compared to what you could achieve with reflection thanks to smarter runtime resolution.
  • Less ugly code in those places, thanks to not having to use reflection or any other crazy mechanism to circumvent inability of making dynamic calls.

I hear that you say that this may be abused in the multitude of ways. Well – yes, no compiler or language let’s you stop thinking (and if there were such compilers or languages, we’d be out of job!). That is the case with everything though. C# has support for pointers, you know? It was added to deal with certain narrow range of scenarios, and it was there since v1.0 but I don’t see it used all over the place by anyone. Heck, there are features in the language many experienced developers didn’t even heard about, left alone used them. Example? – stackalloc keyword. Did you know about it? Have you seen actually code that uses it? I haven’t.

You can cut yourself with just about anything. We want more power in the language, but with power comes responsibility. The dynamic keyword hugely helps in certain scenarios, and if used wisely can do you nothing but good.

To wrap it up, I think the whole situation is best described by this quote from Andy Baio:

I’m sure that the moment man discovered fire, there was some guy nearby saying, “Too smoky. Can burn you. Lame.

Technorati Tags: ,

Subtext – ‘Item with the same key has already been added’ error fixed (hopefully)

Many people visiting my site (myself included) have stumbled upon this error message:

subtext_error

I took some time yesterday and, since Subtext is an open source project, I looked into the code trying to find what’s causing it, and fixed it. I don’t know Subtext’s architecture all that well, so I may have broken something on the way. My error log shows no exceptions (as compared to quite a few a day before the fix), so either people stopped visiting my site, or I fixed it smile_regular without breaking anything else.

If I’m wrong, and you do find any errors on the site, please leave a comment under this post.

Technorati Tags:

Come on, people – really?

dark_knight

Really? Is The Dark Knight the best film ever? Come on…

And if it really is half as good as they say, why do I have to wait two more weeks to see itsmile_cry

Technorati Tags: ,

SourceForge and OpenId

SourceForge has implemented OpenId, and as you can read here, they’re very proud of it.

You’ve been asking for it, and now you get it – SourceForge.net has implemented OpenID. It’s a great way to let you cutting-edge web users to more easily get involved on our site. This helps you participate in the Open Source community – whether you’re helping out in project trackers, starting a new project, or just throwing down in the Community forums. We’re helping you to help us help you some more.

As we all know, the main and greatest advantage of OpenId is that it’s one centralized identity provider, so that you don’t have to have thousands logins/passwords for each and every website you use.

Well, it looks like not everyone understands that.

I wanted to login to aforementioned site to be able to post comment on one project’s forum. Their login/create account page looks like this:

sf_login_openId

Can you see, the right-side window? It says – “Log in with OpenId”. Notice also the “OpenId eliminates…” text below.

I did all the required steps, and instead of being logged in, and able to post to forum, I saw this:

sf_login_openId2

Why does it ask me to create an account? What’s the point of using OpenId, if I still have to create another SF account with another SF login and another SF password. And no – the fact that I don’t have to provide them the next time I ‘log in’ with my OpenId is not a justification.

This is the purest form of abuse of OpenId I’ve ever seen, and having slogans like “OpenID eliminates the need for multiple usernames across different websites, simplifying your online experience.” is just laughing in the face of a user.

Technorati Tags: ,

Everyone has to start somewhere

Today I found post from Ayende, called What I did on 2005. It’s a repository of links to posts from his blog in 2005 summing up the most important things he did. With posts like “Learned to use Subversion“, “Got into testing UI“, “published first OSS project“.

It got me thinking – to get good at something you have to start somewhere. No one is great right from the start, and everyone has to start somewhere.

I’m not sure why but I found it very positive.

Twitter

Ok, in case anyone cares, I set up an account on Twitter. I’m trying to set it up, and figure out why people seem to love it so much. I downloaded an Adobe AIR-powered client called Twihrl, and I find its UI experience… different. I also put a Twitter widget on the blog. We’ll see what hatches out of this.

Technorati Tags: ,

I possess all the knowledge

I found those images great analogy to how, we not-so-humble programmers learn: languages, design, frameworks. (All images by Chris Jordan). For the sake of discussion let’s use learning a language, as an example. This can be however extended to anything.

First, we read, or hear about that new cool language. So we grab some introductory book, or attend a presentation on it. After a day or two, one might say confidently to himself: It’s great, my hello world runs flawlessly and I’m proud of myself.

Life’s good. I know the syntax, I know how the syntax for while loop looks like, I know all the primitives in the language, and I even know how to use those fancy features like delegates, although I don’t understand why they put it there. They’re obviously useless! Well, nevermind – I’m a pro. 

That’s the level at which we think we know all there is to know about the language. Like with the picture above. All we see, is woman’s breastssmile_teeth. That’s the level where we concern ourselves with issues like how to create a class, what’s the difference between public and internal method, and what the heck is the difference between class and structure?

Then comes the first actual project where we can use the skills and knowledge we’re so confident to posses, and eager to put into practice. At that point we might discover things like, that those delegates can actually be put into some good use. They can be passed around as parameters to other methods, and they do the magic that enables me to double-click a button and have the method-stub generated that would be executed when a user click the button during runtime.

At this point we begin to realize, that maybe there’s more to that picture than just breastssmile_wink. We concern ourselves with questions like, how to make that piece of code more reusable, how the Dispose pattern works, and what the heck are those Attributes?

Then, after some time and few projects done, few books read, and few long debugging sessions we come to realize: I know nothing except the fact of my ignorance. That’s the point when we know that delegates allow for decoupling of classes, Attributes among other things are used for meta-programming and classes and structs are oceans apart (or at least as far, as heap form the stack). That’s the point when we concern ourselves with things like manageability, loose dependencies, programming for interfaces rather than implementation etc. That’s the point when we no longer see breasts. We see things as they really are.

Technorati Tags: ,