Greco Giuseppe wrote:

Hi Ian,

I think it would be preferable to have a common
resource assembly (e.g. NAnt.Resources.dll).


you mean all resources for every assembly all in a single resources assembly ? - I don't much like that idea at all. Resources should be located together with the assembly that uses them in most cases. To be honest I'd rather store duplicate copies of strings in different satellite assemblies that merge all the satellites into a single monolithic one.

Letting an assembly access resources of another
assembly and viceversa is not that elegant. Moreover,
it would be difficult to maintain messages consistently.



Why ? It should work the same way as programmatic dependencies - ie if a message is shared between NAnt.Core and NAnt.DotNet then it should be stored with NAnt.Core as it will always be loaded when NAnt.DotNet is ( because of the way the dependencies work ). If pulling a resource string out of another assembly would result in that assembly being loaded when it wouldn't otherwise have been ( eg NAnt.Win32 loading somthing out of NAnt.Documenter.NAnt ) then storing a copy of the string in each would be a better solution.

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.



Actually can you explain to me why the lock is even necessary ? Resource information is read-only so I don't see that there should be any contention issues caused by multiple threads accessing the ResourceManager.

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...


I think all that seems way to complicated - why do we need to register assemblies at all. We can create a new ResourceManager instance every time a resource is requested like :

new ResourceManager(assembly.GetName().Name, assembly))

Is there a huge overhead to doing that that we should be concerned about ?

Ian


------------------------------------------------------- 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

Reply via email to