Themelia Pro A powerful new development platform built on ASP.NET.
 
Understanding Assembly Localization
 
 
Themelia Pro provides various mechanisms to aide in web site as well as non-web application localization. One of these mechanisms in the assembly and web site localization feature. When localizing assemblies, you have many problems to overcome. First, you have to know what cultures to support before publishing your product. Second, cultures are tightly coupled to the logic of the assembly by placing them in the assembly. Third, you have to recompile and re-publish your application every time you want to add a new culture. Then, when localizing your web site, you have a whole new host of problems and the fact that web sites don't natively support localization (which is actually a good thing, localization should be decoupled from your assemblies and web sites.) Themelia Pro provides a model to follow to ensure that you can add culture to your applications and web sites with the simplicity of copying an assembly. Implementing this model is as follows: First, create your initial and primary Resource.resx file in an assembly. This could be a language specific assembly or any other assembly for your application or web site. Next, create a project for each other culture you want to support, putting a single Resource.resx file in each. The name of each assembly must be of the following pattern: AssemblyName-TwoDigitCode. For example, to localize ABCCorp.Web for Spanish and French, you would create an a project called ABCCorp.Web-es and another called ABCCorp.Web-fr. You may also use a four-digit code to be more specific. The Resource.resx file in each file would have the same resource keys as your default culture Resource.resx, but would have the values for that specific language. At this point, you have everything required to use Themelia Pro's localization model. However, to use it, you must first tell Themelia about it. You do this by registering the localization set with the resource accessor by calling the RegisterResourceManager method. Below are the overloads for this method.
public static void RegisterResourceManager(String assemblyName);
public static void RegisterResourceManager(String assemblyName, Boolean allowGC);
public static void RegisterResourceManager(String assemblyName, String assemblyNamePattern);
public static void RegisterResourceManager(String assemblyName, String[] builtInCultureArray);
public static void RegisterResourceManager(String assemblyName, String assemblyNamePattern, Boolean allowGC);
public static void RegisterResourceManager(String assemblyName, String assemblyNamePattern, String[] builtInCultureArray);
public static void RegisterResourceManager(String assemblyName, String[] builtInCultureArray, Boolean allowGC);
public static void RegisterResourceManager(String assemblyName, String assemblyNamePattern, String[] builtInCultureArray, Boolean allowGC);
Different overloads provide different levels of customization. The assemblyName parameter is the only parameter common to each of the overloads. This parameter specifies the full name of the assembly. An effective way to access the full name is shown in the following example code, commonly places in your project's AssemblyInfo.cs file: namespace ABCCorp.Web { public static class AssemblyInfo { public static String AssemblyName = typeof(AssemblyInfo).Assembly.FullName; } } Some of the overloads allow you to change the assembly name pattern. This is the pattern used to look for the localized assemblies. You specify this pattern by using the codes {AssemblyName} and {Code}. The default is "{AssemblyName}-{Code}", which will match assemblies with names like ABCCorp.Web-es and ABCCorp.Web-fr. One important, yet optional parameter is the builtInCultureArray parameter. This parameter is used to tell the resource accessor what cultures are compiled into the assembly. This parameter is a String array of two-digit culture codes. When the resource access knows that a user is of a culture that is built into the assembly, the resource accessor knows that it can look inside the assembly without having to try to reference an external assembly, thus increasing efficiency. Some of the overloads allow you to specify whether the registration may be garbage collected by setting allowGC to true. When true, the loaded resource data will be garbage collected often. Take care in using this feature as it may cause excess garbage collections and, therefore, excess resource re-loading. Here is an example of using the RegisterResourceManager method: Themelia.Globalization.ResourceAccessor.RegisterResourceManager(AssemblyInfo.AssemblyName, new String[] { "en" }, false); Once the assembly is registered, you may then simply access resources via the GetString method. This method also has various overloads:
public static String GetString(String resourceKey, String baseAssemblyName, ResourceManager defaultResourceManager);
public static String GetString(String resourceKey, String baseAssemblyName);
public static String GetString(String resourceKey, String baseAssemblyName, String[] builtInCultureArray);
public static String GetString(String resourceKey, String baseAssemblyName, ResourceManager defaultResourceManager, String[] builtInCultureArray);
public static string GetString(string resourceKey, string baseAssemblyName, ResourceManager defaultResourceManager); public static string GetString(string resourceKey, string baseAssemblyName); public static string GetString(string resourceKey, string baseAssemblyName, string[] builtInCultureArray); public static string GetString(string resourceKey, string baseAssemblyName, ResourceManager defaultResourceManager, string[] builtInCultureArray); The first of these overloads is the most commonly used. This one specifies the resource key, the name of the assembly as specified by the registration method, and then the built-in assembly's resource manager. When the user requests a culture that is built-in, this resource manager is used without needing to look to external references. The second method will only be used if there are no resources in the assembly. That is, all cultures will require lookup via external assemblies. This is not recommended as it doesn't specify a default. The last two overloads are the same as the first two, but that they also register the resource manager if not done so already, thus eliminating a step. Here is an example of using the GetString method: Themelia.Globalization.ResourceAccessor.GetString("Dialog_About_Text", AssemblyInfo.AssemblyName, Resource.ResourceManager); As this point, you may just compile your culture assemblies and make sure they are in the assembly path (i.e. in Bin or another path where .NET knows to look).

A Simplified Process

To simplify the above mechanics, it's highly recommended that after you create your initial resource manager (i.e. your resx file) and setup each assembly, you do the following two things: first, add the previously mentioned AssemblyInfo class and second, add a class similiar to the following. This class will be how you access all resources your entire application or web site: Simplifier: using System; //+ namespace ABCCorp.Web { public static class CorporateResource { //- @Ctor -// static CorporateResource() { Themelia.Globalization.ResourceAccessor.RegisterResourceManager(AssemblyInfo.AssemblyName, new String[] { "en" }, false); } //+ //- @GetString -// public static String GetString(String key) { return Themelia.Globalization.ResourceAccessor.GetString(key, AssemblyInfo.AssemblyName, Resource.ResourceManager); } } } Then, just use the following to access resources: CorporateResource.GetString("Dialog_About_Text") This way you have the full power of decoupled cultures as well as a very simple syntax.