There are also performance issues; actually, the code for getting a localized string is as following:
public static string GetString(string name, CultureInfo culture) { if (resourceManager == null) { lock (typeof(ResourceUtils)) { if (resourceManager == null) { Assembly assembly = Assembly.GetCallingAssembly(); resourceManager = new ResourceManager( assembly.GetName().Name, assembly); } } }
return resourceManager.GetString(name, culture); }
In the code above, the lock takes place only once (the first time a string is retrieved), assuring good performance.
In the code above, there are unfortunately also correctness issues.
Ref: http://weblogs.asp.net/oldnewthing/archive/2004/05/28/143769.aspx http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf
The article on this page seems to imply that DCL is fixed in .Net, but they still recommend using simple static initialisation.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/singletondespatt.asp
Also, I very much doubt that DCL is fixed in .Net... any virtual machine with a memory model that would allow DCL to work without explicit volatility would be unlikely to be performant in multithreaded situations in which volatility were not required.
It's possible that DCL with an explicitly volatile member will work in .Net, but I'm not familiar enough with .Net's memory model to know if this is actually the case.
Adding the functionality to register additional assemblies, the lock would take place always as demonstrated in the following code chunk:
static ResourceUtils() { resourceManagerDictionary = new ResourceManagerDictionary(); }
public static void RegisterAssembly(Assembly assembly) { lock (resourceManagerDictionary) { resourceManagerDictionary.Add(assembly.GetName().Name, new ResourceManager(assembly.GetName().Name, assembly)) } }
public static string GetString(string name, CultureInfo culture) { string localizedString = null; ResourceManager resourceManager = null;
lock (resourceManagerDictionary) { foreach (DictionaryEntry entry in resourceManagerDictionary) { resourceManager = entry.Value as ResourceManager; localizedString = resourceManager.GetString(name, culture);
if (localizedString != null) { break; } } }
return localizedString; }
The methods RegisterAssembly() and GetString() must be kept synchronized...
What do you think about?
Why doesn't GetString in this section restrict itself to the ResourceManager for the calling assembly?
On an unrelated note, is there any reason you use a static initialiser block instead of inline initialisation of your static member?
Regards,
-- Troy
------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ nant-developers mailing list nant-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nant-developers