[Money Pattern] Currencies
In the past blog I introduced the concept of Currency. It was really poor in terms of functionality since I have to set all its characteristics (symbol. name and ISO 4217 code) every time. It would be useful to have an internal table containing all currencies of the world:
internal sealed class CurrencyTable : Dictionary<string, Currency>
{
private static volatile CurrencyTable _table;
private static object syncRoot = new Object();
private CurrencyTable()
{
this.Add("EUR", new Currency("EUR", "Euro", "\u20AC"));
this.Add("USD", new Currency("USD", "Dollars", "\u0024"));
this.Add("CAD", new Currency("CAD", "Dollars", "\u0024"));
this.Add("GBP", new Currency("GBP", "Pounds", "\u00A3"));
}
private static CurrencyTable Table
{
get
{
if (_table == null)
{
lock (syncRoot)
{
if (_table == null)
_table = new CurrencyTable();
}
}
return _table;
}
}
public static Currency GetCurrency(string isoCurrencyCode)
{
string key = isoCurrencyCode.ToUpper();
if (Table.ContainsKey(key))
return Table[key];
else
return new Currency();
}
}
The the above code I made two choices:
- If the currency doesn't exists in the table then get the default (eur) instead of raising an KeyNotFoundException
- I fill the currency table from the code. I could use a resource file (better) instead.
Now, I can add a new Currency constructor which lookups the currency from its ISO code:
public Currency(string isoCode)
{
ISOCode = isoCode;
Currency lookup = CurrencyTable.GetCurrency(isoCode);
if (lookup != null)
{
Name = lookup.Name;
Symbol = lookup.Symbol;
}
}
And set two new Money constructors:
public Money(decimal amount, string isoCurrencyCode)
{
_amount = amount;
_currency = CurrencyTable.GetCurrency(isoCurrencyCode);
}
public Money(decimal amount, Currency currency)
{
_amount = amount;
_currency = currency;
}
With the last constructor I can refactor the arithmetic operators so that they consider also the currency:
public static Money operator +(Money a, Money b)
{
CheckCurrency(a, b);
return new Money(a._amount + b._amount, a.Currency);
}