Is there a better way of managing localized strings? - c#

I work on a product where we have to worry a bit about localization. Currently, this is the workflow for when I have to use(or add) a localized string:
Search resources.resx file(which has hundreds of items)
If found, then copy the name. Otherwise, add a new string and copy the name
Then, use ResourceFactory.ResourceMgr.GetString("MY_MAGIC_STRING") (where ResourceMgr is just a static field to a ResourceManager)
This 3 step process for any strings is a real pain. Are there any patterns or ways to make this process easier?

Auto-generated files with access to each individual string are much easier to use - set "Custom tool" for RESX file to PublicResXFileCodeGenerator.
Code would look like:
using MyProject.Resources;
...
localizedText = Resources.SomeReasonableName;
Side notes:
having multiple RESX files along with auto-generated IDs have additional benefit of intellisense giving you reasonable number of choices.
depending on how translation is handled you may be better not worrying about duplicated text in RESX file (except maybe OK/cancel kind of strings). It may be easier to deal with duplicated strings at translation time.

There is this Java solution that might give you some ideas:
http://rodionmoiseev.github.com/c10n/
The idea is to store translations in the source code itself, using annotations on interface methods. Then, by using a special utility, you can dynamically create proxies (classes dynamically implementing the interface) that would return localised string value when invoking the interface method.
This way, "MY_MAGIC_STRING" is replaced with a call to MyMagicString() method, which gives you some spelling/type safety and makes it more refactoring friendly.

Related

How to select between different Resource files in .Net?

I'm trying to figure out how to choose between two different (identically designed) Resources files in code. All of the examples I can find online are in reference to having different language specific Resource files which are chosen based on setting the culture value. That won't work for my probelm.
This is a web service which returns an image from one of several different image repository systems. Depending on a parameter passed in to the method, the service will need to access an image repository system in order to pull the image being requested. When accessing the image repository, there are a bunch of "magic string" GUID values that represent different IDs for various lookups in that system. One of the purposes of this service is to hide all of that complexity from the user. Rather than hard-code these GUIDs into the code, I have put them into a Resources file.
The problem is this: Each different image repository system has the same set of magic string IDs that need to be used. However, the actual GUID values for these magic strings are different depending on which repository you are connecting to. For example, there is a value called "GroupIDPrompt" which might be "8a48f393642a753f0164418b670a7cdf" on one system, but "63aa28c3637b58680163b25f7e5a5d96" on a different system. In code, I'd like to refer to this value as just "Resources.GroupIDPrompt" or something similar, but I need to be able to set which Resources file will be used at runtime, based on what the consumer of the service sent me.
Normally, I might solve a problem like this by using an interface, and instantiating a specific implementation of that interface based on the request. There are two reasons that doesn't work here - #1, Resource code files are generated automatically, and if I edit them to make them inherit from an interface, this will get broken everytime the file is regenerated. #2, All resource values are created to be static members, and interfaces aren't allowed to declare static members.
I could throw the Resources files away and instead build a class to expose these values, but that means re-introducing magic hard-coded strings to my code. That isn't too terrible, I suppose, but the Resource editor is really quite handy for managing and editing these values.

Centralized vs local string resource files

I am trying to figure out whether a global string resource file for the entire application or a local resource file for each small sub area would be a better choice.
It seems like a translator would appreciate the one file approach vs hundreds of them. It is also easier to write helper functions since there is only going to be one static resource class.
The downside is that the resource name might be really long to properly identify the place where it is suppose to be in and it might be hard to locate related strings when the file grows big.
Where as a local resource file would produce lots of duplicated strings or make it confusing if we need to use multiple instances of static resource classes because the strings are spread between multiple of them.
So what would be a better way to go?
Maybe you could break your resources into 3 files (depending on your application design):
ResourcesCore
For translated enum values and common expressions
ResourcesEntity
For strings related to translation of some entity properties (e.g. Person.Name)
ResourcesWeb (or ResourceUI)
For other UI related stuff (like strings on UI, labels, descriptions, etc.)
You could then use ResXManager extension for VS to manage you resource strings (way easier than native .NET ResX manager, at least for me).

C# What are the Advised Coding Practises to place Constant String Literals in Class

Where is the best place to put string literals within the class? Should they be declared as constant members, should they be referenced in the method (provided the string literal is only ever used once), should they be put in a helper class or elsewhere?
Are you referring to strings that are displayed to user and require internationalization?
In .NET and Java you can use Resource Files that lets you use a key/value resource file. This has the added advantage of not needing compilation every time you need to change text, and you don't need to be a coder to be able to modify the resource files.
If you're just talking about internal strings that are used (like keys, IDs etc.) then I wouldn't fuss too much about it - some people like "constants.cs", while other like it within the file that is using them, and others like putting each set of constants in their own relevant packages. Just keep it ... Constant.

How to access common namespaces for XML parsing

I have stored my common namespaces used in my Linq to Xml parsing in a config file. Where is the best place to access them in my application? Put them in my base class? Create a Config Class that I can call (call namespaces via accessors), ? What would be deemed a good practice here. I currently have about 7 namespaces.
Thanks,
S
What is the requirement? You currently have the namespaces in a config file which allows you to change them without recompiling the application. If you feel this is useful, I would keep them in the file and, as you suggest, create a type to hold the values at runtime which can be passed as a dependency to any code which needs to know about the namespaces.
If however, you expect these namespaces to fixed for ever, it may be reasonable to hard code them into your base class or wherever else in the source code makes sense (this could also be done using embedded resources rather than string literals).
This latter option would have the benefit of reducing unnecessary noise in your config file and the need for the added dependency type, but I would suggest that, in most cases, it's probably just as well to use the config file pattern regardless. Yes it may be a little extra clutter, but in this business things that you think will never change have a habit of changing.
Also, you say that you currently have 7 namespaces. This suggests to me that you think you may have more or less in the future. For this reason, it sounds like you probably should be using the config file pattern.

C# How to create objects without class definitions?

Is it possible to create objects at designtime without having to have hard coded class definitions, then populate properties with primitives or even strongly typed data types?
This might sound confusing, so I will attempt to give you a use case scenario.
Use case:
You have an XML config file that could hold configuration values for connecting to various systems in an SOA application. In C# the XML file is read, but for each system the configuration properties are different (e.g: SQL might have a connection string, while SharePoint might need a username + password + domain + url, while yet an smtp server would need username + password + port + url)
So instead of creating static classes as follows
public class SharePointConfiguration or public class SQLConfiguration, then have each class with custom properties (this is cumbersome)
or
using a 1990's method, an ArrayList or some named collection
Is there not a more preferred way to achieve this? Taking advantage of new language features, that can still offer design time intellisense, which would make the code easier to maintain and less prone to error.
I guess I am looking for some kind of multipurpose .net 4 property holder.
Thanks
Use this sample implementation of a PropertyBag.
If property doesn't exist, create it on the fly...
http://www.codeproject.com/KB/recipes/propertybag.aspx
If you want emit code at runtime?
Checkout the Reflection.Emit namespace
OR better
RunSharp - nicer API
What you want is XML, based on a schema. This will give you IntelliSense, including code snippets, at the same time as providing flexibility.
Based on your question (and assuming I'm reading it right), that would be impossible. The closest you could get would be to use the 'dynamic' type and assign your values to properties at runtime on it - the problem being, that dynamic has no Intellisense support, and even with some other kind of solution, the Intellisense would not be available because the properties would only be attached at runtime.
Am I confused on what you are asking?

Categories

Resources