using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Developpez.Dotnet.Properties;
using Developpez.Dotnet.Reflection;
namespace Developpez.Dotnet.Language
{
///
/// Fournit des descripteurs pour les devises connues
///
public static class KnownCurrencies
{
private static readonly object _currencyLock;
private static readonly Dictionary _providers;
private static readonly Dictionary _bestProviders;
static KnownCurrencies()
{
_currencyLock = new object();
_providers = new Dictionary();
_bestProviders = new Dictionary();
LoadProviders(typeof(KnownCurrencies).Assembly);
}
private static ICurrencyProvider GetProvider(CultureInfo culture)
{
culture.CheckArgumentNull("culture");
ICurrencyProvider bestAvailable;
lock (_currencyLock)
{
if (!_bestProviders.TryGetValue(culture.IetfLanguageTag, out bestAvailable))
{
bestAvailable = FindBestAvailableProvider(culture);
_bestProviders[culture.IetfLanguageTag] = bestAvailable;
}
}
return bestAvailable;
}
private static ICurrencyProvider FindBestAvailableProvider(CultureInfo culture)
{
var candidates = SpellerHelper.GetCultureAndParents(culture).Join(
_providers,
c => c.IetfLanguageTag,
kvp => kvp.Key,
(c, kvp) => kvp.Value,
StringComparer.InvariantCultureIgnoreCase);
ICurrencyProvider bestAvailable = candidates.FirstOrDefault();
if (bestAvailable == null)
throw new NotSupportedException(string.Format(ExceptionMessages.KnownCurrencies_NoProviderAvailable, culture.IetfLanguageTag));
return bestAvailable;
}
///
/// Recherche tous les fournisseurs de devises dans l'assembly
/// spécifié. Utilisez cette méthode pour détecter un fournisseur
/// personnalisé.
///
/// L'assembly dans lequel les fournisseurs de devises sont définis
///
/// Les fournisseurs de devises prédéfinis sont chargés automatiquement,
/// il n'est donc pas nécessaire d'appeler LoadProviders pour les utiliser.
///
public static void LoadProviders(Assembly assembly)
{
var providers =
from a in assembly.GetAttributes()
group a.Culture by a.Implementation into g
let provider = (ICurrencyProvider)Activator.CreateInstance(g.Key)
from culture in g
select new
{
Culture = culture,
Provider = provider
};
lock (_currencyLock)
{
foreach (var s in providers)
{
_providers[s.Culture] = s.Provider;
}
// Clear best choice cache in case a better provider is
// now available for a language
_bestProviders.Clear();
}
}
///
/// Obtient le descripteur de la devise spécifiée pour la culture courante
///
/// Code ISO de la devise
/// Le descripteur de la devise
public static CurrencyDescriptor GetCurrency(string code)
{
return GetCurrency(code, CultureInfo.CurrentCulture);
}
///
/// Obtient le descripteur de la devise spécifiée pour la culture spécifiée
///
/// Code ISO de la devise
/// Culture pour laquelle obtenir le descripteur de la devise
/// Le descripteur de la devise
public static CurrencyDescriptor GetCurrency(string code, CultureInfo culture)
{
return GetProvider(culture).GetCurrency(code);
}
///
/// Obtient la devise Euro (EUR)
///
public static CurrencyDescriptor Euro
{
get { return GetCurrency("EUR"); }
}
///
/// Obtient la devise Dollar américain (USD)
///
public static CurrencyDescriptor USDollar
{
get { return GetCurrency("USD"); }
}
///
/// Obtient la devise Livre sterling (GBP)
///
public static CurrencyDescriptor PoundSterling
{
get { return GetCurrency("GBP"); }
}
}
}